First of all, thanks for webgen. It''s been an invaluable tool for doing static sites. I was a bit overwhelmed by what needed to be done in order to subclass tag classes. The Webgen::Tag::Base is somewhat coupled to a single class and subclasses need to override param() and a couple other base functions to do correct resolution on their superclass''s tag parameters. So, I tried to code up a simple solution that shouldn''t break the current tags (but I haven''t tested it on the Webgen base yet), but I''m wondering what you all think about the current situation of tag parameters and if there''s any plans to change it. Here''s what I came up with along with a simple example: module SAD module Tag module Base include Webgen::Tag::Base private # The base part of the configuration name. This is the class name without the Webgen module # downcased and all "::" substituted with "." (e.g. Webgen::Tag::Menu -> tag.menu). By overriding # this method one can provide a different way of specifying the base part of the configuration # name. def tag_config_base(c=self.class) c.name.gsub(''::'', ''.'').gsub(/^Webgen\./, '''').downcase end # The bases of a tag. This returns the tag_config_base name of the current class and all it''s # superclasses. def tag_config_bases c = self.class bases = [] until c == Object bases << tag_config_base(c) c = c.superclass end return bases end # Return the list of all parameters for the tag class. All configuration options starting with # +tag_config_base+ are used. def tag_params_list param_list = [] #This can be simplified if there''s no duplicate keys in config? tag_config_bases.each do |base| param_list.concat website.config.data.keys.select { |key| key =~ /^#{base}/ } end param_list end # Return a valid parameter hash taking values from +config+ which has to be a Hash. def create_from_hash(config, params, node) result = {} config.each do |key, value| found = false if params.include?(key) result[key] = value found = true else tag_config_bases.each do |base| if params.include?(base + ''.'' + key) result[base + ''.'' + key] = value found = true end end end unless found log(:warn) { "Invalid parameter ''#{key}'' for tag ''# {self.class.name}'' in <#{node.absolute_lcn}>" } end end result end end class CustomMenu < Webgen::Tag::Menu include Base # Create the not nested HTML menu of the +tree+ using the provided +context+. def create_output_not_nested(context, tree, level = 1) submenu = '''' out = "<div id=\"top-nav-menu\">" tree.children.each do |child| submenu << (child.children.length > 0 ? create_output_not_nested(context, child, level + 1) : '''') style, link = menu_item_details(context.dest_node, child.node, context.content_node.lang, level) out << "#{link}" end out << "</div>" out << submenu out end end end end Webgen::WebsiteAccess.website.config[''contentprocessor.tags.map''] [''custommenu''] = ''SAD::Tag::CustomMenu''