Metatheme creates an abstraction layer for web page builder UIs. The goal of Metatheme is to enable a thriving community of web page template builders who can build web page templates that can be used in a wide variety of web site/web page builder user interfaces and products.

Metatheme is both a minimal framework (< 1.5k compressed Javascript) to provide the mechanism to translate a MetaTheme template and some customization into a working web page, as well as a baseline specification for builder user interface controls.

Example

<div style="background-color:
	/*[*/ #773344; /* {"name": "Title", "type": "Richtext",
	"help":
	"This is a little message explaining how to use this substitution.",
	"rect": {"top": 300, "left": 100, "width": 400, "height": 50},
	"system": "title", "mything": "whatever" } " */
">

<span style="font-weight: bold; font-size: 30px; font-family: courier; ">
<!--[-->Title Goes Here<!-- {"name": "Title", "type": "Richtext",
	"help": "The title text for the Thingy. Anything you like.",
	"rect": {"top": 300, "left": 100, "width": 400, "height": 50},
	"system": "title" }  -->
</span>

</div>
	

Download Latest

MetaThemeJS .90

MetaThemeJS .90 (minified)

Design Summary

The design goal for Metatheme is to connect the concept of a "templating engine" (e.g. Handlebars) to a fully functioning HTML/CSS/Javascript document. Unlike normal template engines, the templated code is fully functioning and will look like a particular example of the customized template.

A typical templating engine will produce a jumbled mess should you try to simply put the HTML/CSS/JS document in a web browser statically since it will be riddled with {{substitution tags}} in {{curly brackets}} or some such.

Metatheme uses context-appropriate comment markers as its substitution tags instead of something like "{{" and "}}". This means that MetaTheme documents appear and behave fully functional even when they are statically executed and thus can be more easily developed and tested.

The typical workflow consists of the following:

  1. Create a static HTML/CSS/Javascript document that looks and operates how you want it to. In other words, just code away as you normally would to make a document look one particular way.
  2. Add Metatheme tags to HTML elements and/or CSS styles, or Javascript code. Adding metatheme.js will allow you to compile a given document (viz. the current one) and produce a context object.
  3. Using the mechanism of your choice (viz. your own custom UI), allow your users to manipulate the context object (and/or manipulate it with your own code, or whatever).
  4. Using the metatheme.js, transform the given context object into a new document with the given modifications.
  5. Persist the output (which is an HTML document / fragment) somewhere as desired. The output of the generator will continue to include the original substitution metadata, so further modifications can be made on that document, and so on.

API / Usage Examples

Note: these examples assume you are using jQuery, but that is not required by Metatheme.

Process an Entire HTML Document

$(document).ready(function() {
	var mTheme = new Metatheme($("html").html());

	if(!(mTheme.isError)){
		// do stuff with your Metatheme object:
		// it will have the whole document along with all substitutions found in an array
		// called "subs"; each object in that array will have all of the members of the
		// object you placed between in between the markers in your document, along with
		// other internally used monitors to allow Metatheme to do its thing.
		console.log(mTheme.subs.length);	// print out how many subs we found
	}
	else {
		// otherwise errors will have been spit out in the console...
	}
});
	

Create a New Document From a Modified Metatheme Object

var templateObj;

$(document).ready(function() {
	templateObj = new Metatheme($("#themedLayoutArea").html());

	if(templateObj.isError){
		// stop the world, there was a parse error in your document...
	}
});


$("#rename_title_button").click(function(e){
	// rename the title to "foo the bar" and redraw the theme
	templateObj.findSubs("title").value = "foo the bar";

	$("#themedLayoutArea").html(templateObj.generate());
});
	

Vars as JSON Strings

MetaThemeJS vars are JSON strings which are turned into active JavaScript objects. The "name" property determines the name of the var.

String literals in HTML tags (e.g. A HREF="bla" or IMG SRC="bla") require a special approach to substitution. In this case you include the whole HTML tag between your substitution markers and then you must include the "subTagName" attribute in your variable spec, and specify the name of the HTML string literal value to wholly replace. For example:

	<!--[--><img src="/images/my_example.jpg"><!--
		{"name": "Your Picture", "type": "ImageURL",
		"help": "A picture of yourself.",
		"rect": {"top": 300, "left": 100, "width": 400, "height": 50},
		"subTagName":"src" }
	-->
	

In this case, the parser will look for the "src" literal and replace the contents of it's value. Note that the value is case-specific and must have the exact format, 'tagValueSub=' (with no space before or after the = character). The parser will look for either a single or double quote around your literal, and use whichever one you used before.

Data Types and Type Reference

As a standard JavaScript object, MetaTheme vars can have any number of properties. The make-up of the properties will consist of some common definitions (see below) that should be included in all MetaTheme vars. Beyond that, different data types may include properties specific to that type. Beyond that, properties may include anything that may go beyond the baseline standard (MetaThemeJS doesn't encourage going outside the standard, but doesn't actively discourage it either).

Design note: you'll notice below that some of the standard Types overlap somewhat. This is on purpose. This allows templates to take different approaches to allowing the user to customize their page, and enables templates to be created for a variety of HTML contexts, such as email and mobile.

Also note that the MetaThemeJS framework does not enforce the data type standards, and that only the required properties below are necessary to make the framework function.

Common (required) Properties

name The name of the variable. This may be displayed to the user, so it should be descriptive but short (<25 chars).
type The data type of the variable. See below for a list of valid common data types. The framework itself doesn't enforce valid data types, which means Builder-specific types can be included. Unimplemented types should be ignored by Builders.

Common (optional) Properties

mustchange If present, and set to "true", the user should be prompted to change the default value of this variable to something new before saving as their new document.
help A string to briefly (80 chars or less) describe the var to the end-user.
email If present, and set to "true", present the user with options appropriate to building web content compliant for web email environments.
order If present among more than one variable, the visual order presented to the user will be based on this value, and variables without this property will be presented after in the order they were found in the Metatheme input string (i.e. the Document).
altname If present, an alternate name by which the variable may be found. This is useful for variables that must be located programatically, even though the name of the variable (which is displayed to the user) may need to be changed somewhat based on the particular template, and/or may be presented in a different language.
maxlen If present, specifies a maximum length for length-affected data types (e.g. String and RichText).
objectid If present, specifies an HTML object ID that should be a) highlighted when the given variable is select; and/or b) selected for editing when the given object ID is clicked.

List of Common Types

String A simple string. Can be any length by default. Optional properties: "maxlen" to specify a maximum length.
RichText HTML to be used in an area where text is expected. This text can theorhetically including any HTML tags, but should be limited to tags for text alone (i.e. not images or other layout formatting). Hence HTML tags should limited to SPAN and other non-layout-changing tags. Text style should also include a mode for "default" to allow the user to choose no style at all (and thus use a style from elsewhere in the HTML).

Valid option: email.
TextStyle Exactly the same as RichText, but only the style (CSS) specification for a single strand of text. Otherwise all rules for RichText apply.
Background CSS which describes the background of a DIV tag. Builders should implement color (rgba) as well as image backgrounds. The value is a string of valid CSS code only, as would fit with a STYLE tag, for instance.
ImageURL The URL for an image. Usually used with an IMG tag. Builders should provide only an image chooser here: processing for crop/zoom/etc. should either be done server-side, or by using a full Background type to use CSS client-side processing.
Internal A type meant not to be presented to the UI for the user to manipulate, but rather only to be used for the UI builder itself. This variable should not be presented to the user in any way.