Quick question: my original intention was to set it up so that people could use something like, for example, {{PRICE_OF_FOO}} in node content, so that when the price of foo changes, it only has to be changed in one place rather than in lots of different places. Rather than reinvent the wheel, I've used Token + Token Filter, so that people can use [token custom price-foo]. Everything works fine with: function custommodule_token_values($type, $object = NULL, $options = array()) { if ($type == 'custom') { $tokens['price-foo'] = "$19.99"; return $tokens; } } The next step was to stick a UI on this so anybody can update the price. To do so I created a new content type "tokens", and added CCK fields for foo_price, foo_version_number etc. The code now looks like: function custommodule_get_tokens(){ $node = new stdClass(); $node->nid =12; $node->vid = db_result(db_query("SELECT vid FROM {node} WHERE nid = %d",$node->nid)); $node->type = 'tokens'; $content = content_storage('load', $node); return array("price-foo"=>$content['field_foo_price'][0]['value'],"version-foo"=>$content['field_foo_version_number'][0]['value']); } function custommodule_token_values($type, $object = NULL, $options = array()) { if ($type == 'custom') { $tokens = custommodule_get_tokens(); return $tokens; } } Basically: is this the best way to do this, or is there a simpler/more native to giving users node tokens they can edit themselves. I wanted to check before I embarked on a round of clearing up the UI so that the "tokens" content type doesn't have all the menu/published/language stuff on etc, making sure people can't hit node/12 etc.