Key Values Plugin

Yes, I realize Movable Type is not a general-purpose content management system, but if you're in a pinch it can do wonders. Especially with this plugin, which allows you to associate other bits of data with your entries which can be extracted conviently in your templates. (Click the more link for more information.)

Availability

You can download this plugin here: mtkeyvalues-1_53.zip

Installation

To install, place the 'keyvalues.pl' file in your Movable Type 'plugins' directory. The 'keyvalues.pm' file should be placed in a 'bradchoate' subdirectory underneath your Movable Type 'extlib' directory. Your installation should look like this:

  • (mt home)/plugins/keyvalues.pl
  • (mt home)/extlib/bradchoate/keyvalues.pm

Refer to the Movable Type documentation for more information regarding plugins.

This plugin has a tag called "IfKeyMatches" that requires the 'regex' plugin, also available from my web site.

Description

This plugin allows you to store key/value pairs of data in your Movable Type fields. These values can be extracted and used in your templates in a very flexible manner.

Tags made available through this plugin:

  • <MTKeyValues>: Container tag for accessing your key/value data.
  • <MTKeyValuesHeader>: Lets you print a 'header' block within an iterating KeyValues tag.
  • <MTKeyValuesFooter>: Lets you print a 'footer' block within an iterating KeyValues tag.
  • <MTIfKeyExists>: Tests whether a key exists (given a name).
  • <MTIfNoKeyExists>: Tests whether a key does not exist (given a name).
  • <MTIfKeyMatches>: This tag will test the name of a key against a value or pattern. Note: if matching against a regular expression, this tag will require the 'regex' plugin (see installation instructions above).
  • <MTIfKeyNotMatched>: Outputs contained text if a given key is not matched using a 'IfKeyMatches' tag.
  • <MTKeyName>: Outputs the name of a key (only useful when iterating over key/value pairs).
  • <MTKeyValue>: Outputs the value of a key. Can output value by name or will output the value of the current key when iterating over key/value pairs.
  • <MTKeyValuesStripped>: Outputs the source of your key/value pairs without the key/value data. This allows you to retain the use of your field(s) for regular blog data and use them to store key/value data at the same time.

<MTKeyValues>

These attributes are allowed:

  • delimiter: Defaults to '='.
  • pattern: Only processes key/value pairs matching the regular expresssion provided. (Requires 'regex' plugin-- see installation instructions above.)
  • source: Defines the source of the key/value pairs. Default source is the current entry's 'Additonal Text' field.
  • iterate: if this attribute is given (ie: iterate="1"), then the contained data is output for each key/value pair that exists.

This tag has two modes of operation. The normal way it works it to output anything contained within the tag once (regardless of the key/value pairs you have defined). The other way is to output the contained data multiple times for as many keys you have defined.

Examples:

Given an 'additional entry text' of this:

 Blah blah blah. Blah
 blah blah.... This is
 the regular text
 followed by the key/value
 pairs which are in the form of key=value.
 rating=3
 link=http://www.bradchoate.com/
 name=Brad Choate

And a portion in an 'Individual Archive Template' like this:

<MTKeyValues>
Extended entry (without key value data):
[[<MTEntryMore>]]<br />

Name: <MTKeyValue key="name"><br />
Link: <a href="<MTKeyValue
  key="link">">
    <MTKeyValue
  key="link"></a><br />
<MTIfKeyExists key="rating">
Rating: <MTKeyValue key="rating"><br />
</MTIfKeyExists>
<MTIfKeyExists key="favorite">
This is my favorite site!<br />
</MTIfKeyExists>
</MTKeyValues>

This will output:

Extended entry (without key value data):
[[Blah blah blah. Blah
blah blah.... This is
the regular text followed by the key/value
pairs which are in the form of key=value.]]<br />

Name: Brad Choate<br />
Link: <a href="http://www.bradchoate.com/">
    http://www.bradchoate.com/</a><br />
Rating: 3<br />

See? The other way to use KeyValues is like this:
Key value pairs:

<MTKeyValues iterate="1">
<MTKeyName>: <MTKeyValue><br />
</MTKeyValues>

This will output (again using our sample data above):

name: Brad Choate<br />
link: http://www.bradchoate.com/<br />
rating: 3<br />

Now you might want to just output some of those key/value pairs:

<MTKeyValues iterate="1" pattern="m/a/">
<MTKeyValuesHeader>
Here are the keys with 'a' in their name:<br />
</MTKeyValuesHeader>
<MTKeyName>: <MTKeyValue><br />
</MTKeyValues>

The above will output all keys with 'a' in their name:

Here are the keys with 'a' in their name:<br />
name: Brad Choate<br />
rating: 3<br />

The 'source' attribute lets you define where your key/values are coming from. The default is the 'additional entry text' field for your blog entries. But you can put key/value pairs anywhere! You might want to store some in your blog description... If you do, this is how you would extract them (note that for the 'source' attribute, you use [ and ] instead of < and > to delimit the MT tags):

<MTKeyValues source="[MTBlogDescription]">
<body bgcolor="<MTKeyValue key="bgcolor">">
</MTKeyValues>

Now that might look weird, but if you have 'bgcolor=#ff0000' in your blog description, this will produce:

<body bgcolor="#ff0000">

A red background-- not recommended for those with weak stomachs!

You can also write multiline values. If you use this syntax in your entry data:

address==
123 Anywhere Street
Anytown USA
==address

Or subsitute your delimiter of choice for '='... you just use two instead of one to indicate the multiline format. To be recognized, there shouldn't be any blank space to the right of the opening '==' and the closing '==' should be at the start of the line. If you want to assign the value of your delimiter to a key, you'll have to write it like this:

mykey==
=
==mykey

<MTKeyValuesHeader>

This tag may be used within the KeyValues tag for producing a header if there are keys available. This is only useful when using the 'iterating' attribute of the KeyValues tag.

<MTKeyValuesFooter>

This tag may be used within the KeyValues tag for producing a footer if there are keys available. This is only useful when using the 'iterating' attribute of the KeyValues tag.

<MTIfKeyExists>

This tag allows you to test for the existence of a particular key.

These attributes are allowed:

  • key: Name of the key to look for.

Example:

<MTKeyValues>
<MTIfKeyExists key="somekey">
  'somekey' exists!
</MTIfKeyExists>
</MTKeyValues>

<MTIfNoKeyExists>

This tag allows you to test for the existence of a particular key.

These attributes are allowed:

  • key: Name of the key to look for.

Example:

<MTKeyValues>
<MTIfNoKeyExists key="somekey">
  'somekey' doesn't exist!
</MTIfNoKeyExists>
</MTKeyValues>

<MTIfKeyMatches>

This tag allows you to test whether or not a given key matches a particular value OR if the value matches a given pattern.

These attributes are allowed:

  • key: Name of the key to test.
  • value: Value to compare against.
  • pattern: Regular expression patten to test the value against.

Example:

<MTKeyValues>
<MTIfKeyMatches key="color" value="blue">
  Color is blue
</MTIfKeyMatches>
<MTIfKeyMatches key="color" value="red">
  Color is red
</MTIfKeyMatches>
<MTIfKeyMatches key="color" value="green">
  Color is green
</MTIfKeyMatches>
<MTIfKeyNotMatched key="color">
  Color is not red, green or blue
</MTIfKeyNotMatched>
</MTKeyValues>

Here's how you would use the 'pattern' attribute:

<MTKeyValues>
<MTIfKeyMatches key="color"
  pattern="m/(red|green|blue)/">
  Color is red, green or blue
</MTIfKeyMatches>
<MTIfKeyNotMatched key="color">
  Color is not red, green or blue
</MTIfKeyNotMatched>
</MTKeyValues>

<MTIfKeyNotMatched>

This tag allows you to output data if a given key has not been matched against using the 'IfKeyMatches' tags.

These attributes are allowed:

  • key: Name of the key to test.

See the 'IfKeyMatches' tag for examples.

<MTKeyValue>

This tag produces the value of a particular key OR if it is within an iterating KeyValues tag, it will print the current value.

These attributes are allowed:

  • default: Expression to use as a default in case the key does not exist. This value can contain nested MT tags in the form of [MT...].

See the 'KeyValues' tag for examples.

<MTKeyName>

This tag produces the key name of the current key from an iterating KeyValues tag.

See the 'KeyValues' tag for examples.

<MTKeyValuesStripped>

Outputs the source of your key/value pairs without the key/value data. This allows you to retain the use of your field(s) for regular blog data and use them to store key/value data at the same time.

Here's how you'd use it:

<MTKeyValues>
  <MTKeyValuesStripped>
</MTKeyValues>

License

Released under the MIT License.

Changelog

  • 1.52: Fix for cases where contents of KeyValues tag is empty..
  • 1.52: Corrected closure tags for embedded expressions.
  • 1.51: Fix for 'source' attribute of MTKeyValues tag.
  • 1.5: 'key' attributes can now be Movable Type expressions. Ie: <MTKeyValue key="[MTSomeTag]">
  • 1.42: Fix to make KeyValues return any errors from MT tags it processes.
  • 1.41: Bugfix for 'pattern' attribute of the KeyValues tag.
  • 1.4: Added multiline support.
  • 1.3: Altered the way key/values are stripped so they don't leave blank lines.
  • 1.2: Addition of the KeyValuesHeader, KeyValuesFooter tags.
  • 1.1: The KeyValue tag now supports a default attribute.
  • 1.0: Initial release

TrackBack

TrackBack URL for this entry:
http://bradchoate.com/mt/feedback/tb/237

Listed below are links to weblogs that reference Key Values Plugin:

» The Photoblog... from gessaman.com
I've had a number of people ask me how I set up my photoblog. Now, I'm not really fond of the concept of spawning a plethora of copycats, but if [Read More]

» The Photoblog... from gessaman.com
I've had a number of people ask me how I set up my photoblog. Now, I'm not really fond of the concept of spawning a plethora of copycats, but if [Read More]

» Rogue Tags, Serendipitous Plugins from Tangleweeds
So I had a major adventure posting yesterday's message, and made an entirely uninformed decision that it happened because the [Read More]

» Rogue Tags, Serendipitous Plugins from Tangleweeds
So I had a major adventure posting yesterday's message, and made an entirely uninformed decision that it happened because the [Read More]

» using key values to store additional information from Al-Muhajabah's Movable Type Tips
The Key Values plugin offers one way to store more information with each entry than you have fields for. I use it on The Clipboard to create the "Other Views" section. There are several services such as Blogdex, Waypath, and... [Read More]

» Key and Values from em-brof
I wonder how I could miss that very specific plugin when I was developping the mBlog system. The plugin allows... [Read More]

» Mirgrated the site to Movable Type from keli.dk
I've just begun using a blog system called Movable Type to administer the site... [Read More]

» Migrated the site to Movable Type from keli.dk
I've just begun using a blog system called Movable Type to administer the site... [Read More]

» MT Plugins Installed from Technology Updates
The following MovableType plugins were installed: From Brad Choate IncludeEx - Improves on MT’s Include tag by processing the included file for MT tags. MTAuthors - This plugin allows you to list the authors for your blog. You can also... [Read More]

» fotos update from . cynics' - /mak'in-trash`/ .
did some _structural_ adjustments to the fotos site as I found out some deficiencies in the way some of my data is being used. [Read More]

» Key Values Plugin from Braindump
Brad Choate: Key Values Plugin utile pour les blogs de livres !... [Read More]

» Testing 1,2,3......is this thing on? from Randy's SoapBox
I’m just testing Brad Choate’s KeyValues plugin… If you see mood and music values at the bottom of this post, it must be working.... [Read More]

» Happy New Year! from CR4D
I’m working right now. Isn’t that fun? Yeah, oh well. I’m getting paid $9 an hour to watch TV and surf the internet, so I guess it could be worse. Anyway, I’ve been exploring the wilds of weblogging and content... [Read More]

» Happy New Year! from CR4D
I’m working right now. Isn’t that fun? Yeah, oh well. I’m getting paid $9 an hour to watch TV and surf the internet, so I guess it could be worse. Anyway, I’ve been exploring the wilds of weblogging and content... [Read More]

» MT용 플러그인, hack, 스크립트 from EOUIA
스크립트 하나를 추가 했는데, 영 맘에 들지 않는다. 좀더 시간을 들여 살펴봐야 할 듯. 아마도, 국내 MT 사용자중 가장 많은 플러그인과 hack, 스크립트들을 달아본 것 같은데, 이쯤해서 한번 중간 정리가 필요할 듯. 지금까지 적용해 본 플러그인, 스크립트, hack등의 ... [Read More]

» Slugs: Decrufting Movable Type URLs from Virtuelvis
A tutorial on how to migrate from the old, numeric Movable Type URIs, to search-engine and user-friendly URLs without file extensions, and with proper, custom slug text. [Read More]

» Slugs: Decrufting Movable Type URLs from Virtuelvis
A tutorial on how to migrate from the old, numeric Movable Type URIs, to search-engine and user-friendly URLs without file extensions, and with proper, custom slug text. [Read More]

» Slugs: Decrufting Movable Type URLs from Virtuelvis
A tutorial on how to migrate from the old, numeric Movable Type URIs, to search-engine and user-friendly URLs without file extensions, and with proper, custom slug text. [Read More]

» Slugs: Decrufting Movable Type URLs from Virtuelvis
A tutorial on how to migrate from the old, numeric Movable Type URIs, to search-engine and user-friendly URLs without file extensions, and with proper, custom slug text. [Read More]

» Slugs: Decrufting Movable Type URLs from Virtuelvis
A tutorial on how to migrate from the old, numeric Movable Type URIs, to search-engine and user-friendly URLs without file extensions, and with proper, custom slug text. [Read More]

» Targeted Disemvoweling the MT Way from Wos waas a Fremda?
I now have a solution to easily and non-destructively disemvowel individual comments. (Disemvowelling was invented by Teresa Nielsen Hayden, praised be her name.) [Read More]

» Website Redesign: Phase II from berbs.us
I recently finished the first major piece of the EduTech website redesign I mentioned earlier: creating a new page layout. You can take a look at a prototype of the new design if you're interested. It's based heavily off a... [Read More]

» Playing With Movable Type 3.2 Beta 4 from berbs.us
I managed to make a lot of progress on the EduTech website redesign yesterday and hope to continue it today. I got the latest Movable Type 3.2 beta release, Beta 4, installed on my PowerMac after compiling Perl DBI and... [Read More]

» CustomFields Plugin: Looking Good So Far from cygweb
I've been overdue to implement a plugin on the Manolas Handmade Soaps site that would allow Melissa to input metadata for each item that would be used to automatically populate the PayPal button form. For simpler items, I asked her... [Read More]

» A few tips about online communities from padawan.info
While watching the launch wreckage of Truemors, I came across a few interesting tips about managing online communities: - It셲... [Read More]

28 Comments

Eliot said:

Hmm... so how do I use test for normal extended entries? I put MTEntryIfExtended inside MTKeyValues, but it is always true then. If I use MTEntryIfExtended outside of MTKeyValues, it shows true when there is keyvalues.

Brad Choate said:

Yeah, I've thought about that. In practice, in the blogs where I have used key/values, I only assign them for entries that have an extended entry anyway. But if you want to have key/values for entries where you don't have any real data in the 'extended entry text' field, you could either:

1) add a key called 'extended' and test for it using the IfKeyMatches tag

2) use the IfEmpty plugin (also found here) and test the EntryMore value (or KeyValuesStripped if you're not storing them in the extended entry field) like this:
<MTKeyValues>
    <MTIfNotEmpty var="EntryMore">
        (there is info left in the extended entry field)
    </MTIfNotEmpty>
</MTKeyValues>

One of those should work for you.

Kief said:

I can't get this to work with the MTCategoryDescription. I do like this in my category archive template:

<MTKeyValues source="[MTCategoryDescription]">
<MTKeyValuesStripped>
</MTKeyValues>

... but when I rebuild I get this error:

Build entry 'The California Boom' failed: Build error in template 'Category Archive': Error in <MTEntries> tag: Error in <MTKeyValues> tag:

With no detailed error message. Perhaps it doesn't know where to get MTCategoryDescription from? I tried it with random source strings ("MTFoo") and get the same message. If I use MTBlogDescription it works. I've had a dip into the code and the MT perldocs, but the learning curve to figure this out myself looks steeper than just asking!

Thanks for the plugins,
Kief

Quadsk8 said:

About another plugin: MTFormatBreaks.

I know you told us it is "not formally ready for release" and on the MTForum you advised on August 23. that there was an update to 1.1 version.
Will you be releasing this after all? or will it maybe get obsolete by MT2.5?
Is there a problem with it for its unofficial state?

Sorry just curious, (also about Seth, how is he?)
Lawrence

Brad Choate said:

I still have some work to do on format breaks-- there are some tags that need special handling. Blockquote for one. I haven't had time to work on it what with the baby and all (and he's doing just great-- thanks for asking!). I hope to revisit that plugin and a couple of others that are 'half-baked' at the moment pretty soon. Perhaps this weekend will yield an hour or two I can use for that.

Quadsk8 said:

Okay I let you work in peace...
But for these question which could be relevant:

Am I right that once you use this plugin, you should put it in every template which has {MTEntryBody} just to be sure formating on main index will be the same as on all the individual etc. pages?

Would it be usefull if it could be applied to {MTCommentBody} as well, or does this work already? (like apply_macros="1")?

On Seth: have you thought about Preventmefromdrivinginsane.com and let your visitors change dipers en do midnight feedings?
Lawrence

Brad Choate said:

I'm assuming we're still discussing the format breaks plugin... yes-- you would have to use the format_breaks attribute for each place your MTEntryBody tag in order for it to be consistent. And yes, you can use the attribute with other tags like MTCommentBody. Just remember to also use the convert_breaks="0" attribute too so that MT doesn't try to format the line breaks itself.

David Raynes said:

Is it possible (currently at least) to combine this with the Macros plugin? I'm currently trying to use a macro of mine within a value, and I'm not getting any output at all.

I'm trying to combine this plug in with the MTAmazon plugin so that MT entries containing a book's ASIN number will display the book title, author, price, image, etc info using MTAmazon. I am able to get this to work when I hardcode the ASIN number into the MTAmazon tag, and I am able to retrieve an "asin=XXX" key value tag, but don't seem to be able to pass that value into <MTAmazon> using the following from within an <MTEntries> loop:

<MTEntries category="Feature" lastn="1" process_tags="1">
<MTKeyValues>
This works: <MTKeyValue key="asin"><br />
<br>
<MTIfKeyExists key="asin">
Found asin -- this shows up
<MTAmazon method="Asin" search="<MTKeyValue key="asin">" lastn="3">
... never reaches here ...
</MTAmazon>
</MTIfKeyExists>
</MTKeyValues>
</MTEntries>

Any suggestions?

Nilesh said:

Brad, can I use html in the key value pairs?

bethlet said:

Brad, These key values are exactly what I need. One question, though. You can specify the place where the key values should be looked for in the source attribute of the MTKeyValues tag. Is it possible to specify the main entry body? I've tried
...
but that doesn't seem to work. Am I doing this entirely wrong?

bethlet said:

Doh. Tag was stripped out. I've tried (MTKeyValues source="[MTEntryBody]")...

Maria said:

Hi!

I've used the KeyValues for a bookreview site of mine and it all worked just fine. I made two lists, one sorted after author and one after title.

The problem is as we entered into 2003 all my reviews from 2002 don't get listed anymore.

Any idea why?

You can see the original discussion here:
http://www.movabletype.org/cgi-bin/ikonboard/ikonboard.cgi?s=3e15b1ad6254ffff;act=ST;f=14;t=11157;st=0

Thanks in advance! :o)

Aaron said:

Is there a way to see if the plug-in is working properly? I can't seem to get it to work in my templates, even copying and pasting examples. I'm wondering if I didn't install properly. (beyond simply copying/pasting files into proper directories?)

Michael Stucker said:

I can't seem to get this to work properly with the multiline output - if I put in this: address== 123 Anywhere Street Anytown USA ==address and use this: <MTKeyValues> <MTIfKeyExists key="address"> Address: <MTKeyValue key="address"><br /> </MTIfKeyExists> </MTKeyValues> I get this: Address: =123 Anywhere Street Anytown USA

Michael Stucker said:

The following hack in keyvalues.pm fixed the extra delimiter:
add this line: $value = substr($value,1);
after this line: if ($value eq $delimiter) {

Jochen Schroeder said:

Is a on the fly replacement possible and when how??
Thanx!

Jason said:

Brad,

Just wanted you to know, I use a great many of your plugins and while they are all great, I've found this one to be amazingly useful!

Keep up the good work!

kristine said:

Is it possible to store the data in a template or module instead of a blog/entry/category/etc. field? <MTKeyValues source="[MTLink template="test"]"> seemed to make sense to me, but that didn't work ;) I'm trying to make key/values for author names and URLs on the mt-plugins.org site
  Brad Choate=http://www.bradchoate.com/
and then be able to use the MTKeyValue and MTKeyName tags to make a list with them or even create macros all at once. I know how to do this with php (that's how I'm doing it currently -
  $authors=array("Brad Choate" => "http://bradchoate.com/ ")
but that's not as useful for pulling the data into xml feeds for the author URL :)

If I didn't make any sense, I do apologize!!! ;)

Ian said:

Hi Ramon,

The line you have:

<MTAmazon method="Asin" search="<MTKeyValue key="asin">" lastn="3">

Should be:

<MTAmazon method="Asin" search="[MTKeyValue key='asin']" lastn="3">

All the best,

--
Ian

Ian Young said:

I've been using this for a while with some success, but am having difficulty getting the header and footer tags to work as described.

What I'm seeing is that the header tag contents get shown on every iteration, and the footer tag contents are never shown.

For example, as input:

<MTKeyValues iterate="1" source="[MTEntryKeywords]">
<MTKeyValuesHeader>
Here are the keys:<br />
</MTKeyValuesHeader>
<MTKeyName>: <MTKeyValue><br />
</MTKeyValues>

Output:

Here are the keys:
KEYA: AAA
Here are the keys:
KEYB: BBB
Here are the keys:
KEYC: CCC

Is there a known problem in this area, or is there a misunderstanding at my end?

Ian Young said:

In partial answer to my own question, I think there is a bug in keyvalues.pm.

I can now get the MTKeyValuesHeader tag working by

(a) adding an $i++ before the end of the loop at line 115 and

(b) replacing the "!defined" clause in line 111 with 0 (false).

However, making the footer tag work looks like I would actually have to know what I was doing, so it will have to wait until tomorrow...

Ian Young said:

Looking at it fresh, the full answer to my question is that there is a bug in keyvalues.pm V1.53 that prevents the MTKeyValuesHeader and MTKeyValuesFooter tags from working correctly.

The good news is that just adding an "$i++;" line before the end of the loop (a new line 115 in this version) fixes both problems.

from Michael Stucker:


The following hack in keyvalues.pm fixed the extra delimiter:
add this line: $value = substr($value,1);
after this line: if ($value eq $delimiter) {

I had the same problem (the second '=' in the block delimiter being output) and it got fixed with Michael's suggested hack. Is this a good hack?

Hossein Derakhshan said:

My text-formating, Textile, is messing up with my key/value entries, while the source is [MTEntryBody]. Is there a way around it?

Toby Beal said:

Brad,

I think the KeyValue Plugin is great. I had no problem copying it into my mt install.

I do however have a question about the MTKeyValuesStripped tag. You see I'm running a news and events Web site. And it was my intention to use key/value pairs to rank certain articles as more important than others. I was able to do this by placeing a key/value pair in the extended entry field, TopNews=T. However I still want to use this field for extended entries. I was hoping that the MTKeyValuesStripped tag would allow me to strip the key/value pair when I displayed the entry on an archive page.

However on my archive page, the key/value pair still shows up. Did I misunderstand the purpose of the MTKeyValuesStripped tag?

Thanks for your help.

how do I strip out the key-value pairs from the entry body on my main index pages?

By enclosing my Extended entry data with a MTKeyValues tag, it strips out the key-values pair, but how do I do that for the bodies? does this depend on the archive type, i.e. will it work on indexes?
thanks.

Nevermind, i figured it out, you have to replace your MTEntryBody tag with an MTKeyValuesStripped, and make sure that enclosing MTKeyValues tag includes the source [MTEntryBody]

About

This article was published on July 27, 2002 8:33 PM.

The article previously posted was PerlScript Plugin.

The next article is Regex Plugin.

Many more can be found on the home page or by looking through the archives.

Powered by Movable Type