You could try a concept base approach:
import strutils
#https://github.com/onionhammer/nim-templates
import templates
type
HasName* = concept x
$x.name is string
HasSubTitle* = concept x
$x.subTitle is string
HasSummary* = concept x
x is HasName
x is HasSubTitle
Sellable* = concept x
x.price is float
Header* = concept x
x is HasName
# must have header proc implemented
header(x)
#Blog is HasName, HasSubTitle, HasSummary, Header
Blog* = object
name*: string
subTitle*: string
#Product is HasName, Sellable, Header
Product* = object
name*: string
price*: float
#Robot is HasName, Header
Robot* = object
name*: int
proc showName*(hasName: HasName): string = $hasName.name
proc showSubTitle*(hasSubTitle: HasSubTitle): string = $hasSubTitle.subTitle
proc discount*(sellable: Sellable, discountPercentage: float): string =
"$" & $(sellable.price - (sellable.price * discountPercentage))
proc summary*(hasSummary: HasSummary, titleH: string, subTitleH: string):
string = tmpli html """
<$titleH>$(hasSummary.name)</$titleH>
<$subTitleH>$(hasSummary.subTitle)</$subTitleH>
"""
# Private Base method equivalent
proc header[T](ob: T): string = """<h1>$#</h1>""" % [$ob.name]
# Private Method override for Robot
proc header(robot: Robot): string = """Model: $#""" % [$robot.name]
# doHeader could be use as the public api for header outside of the module
proc doHeader*(h: Header): string = header(h)
var blog: Blog = Blog(name: "Jim", subTitle: "Jim is funny")
var product: Product = Product(name: "Wheel", price:21.95)
echo blog.showName() # Jim
echo product.showName() # Wheel
echo Robot(name: 1234).showName() # 1234
echo product.discount(0.1) # $19.755
echo blog.showSubTitle() # Jim is funny
echo blog.summary("h1", "h2") # <h1>Jim</h1><h2>Jim is funny</h2>
echo blog.doHeader() #<h1>Jim</h1>
echo product.doHeader() #<h1>Wheel</h1>
echo Robot(name: 41251).doHeader() #Model: 41251
echo "Done!"