There is the classical way: get the main category of the entry, and display a list of entries in the same category, using a code snippet like this below each entry:
<mt:categorylabel setvar="thecategory">
<mt:if name="thecategory>
<h1>Related entries:</h1>
<mt:entries category="$thecategorylabel">
...
</mt:entries>
<h1>Related entries:</h1>
<mt:entries category="$thecategorylabel">
...
</mt:entries>
</mt:if>
A little more sophisticated is to use the tags of the current entry as a basis for loading other entries:
<mt:setvarblock name="searchoptions"><mt:entrytags glue=" OR "><mt:tagname></mt:entrytags></mt:setvarblock>
<mt:if name="searchoptions">
<h1>Related entries:</h1>
<mt:entries category="$searchoptions">
...
</mt:entries>
</mt:if>
<mt:if name="searchoptions">
<h1>Related entries:</h1>
<mt:entries category="$searchoptions">
...
</mt:entries>
</mt:if>
If you use many tags on your site, the above solution might return many matches based on only one or two (very frequent or common) tags. To avoid this, you could use following snippet, which actually counts the number of matching tags and displays the entries with the most matches:
<mt:entrytags><mt:tagname setvar="thetag"><mt:var name="tags{$thetag}" value="1"></mt:entrytags>
<mt:setvarblock name="searchoptions"><mt:entrytags glue=" OR "><mt:tagname></mt:entrytags></mt:setvarblock>
<mt:setvarblock name="searchoptions"><mt:entrytags glue=" OR "><mt:tagname></mt:entrytags></mt:setvarblock>
<mt:if name="searchoptions">
<h1>Related entries:</h1>
<mt:entryid setvar="thisentryid">
<mt:entries tags="$searchoptions"><mt:unless tag="entryid" eq="$thisentryid">
<mt:var name="matches" value="0">
<mt:entrytags><mt:tagname setvar="thetag"><mt:if name="tags{$thetag}"><mt:var name="matches" op="+" value="1" setvar="matches"></mt:if></mt:entrytags>
<mt:setvarblock name="theentry">
...
</mt:setvarblock>
<mt:var name="allentries{$theentry}" value="$matches">
</mt:unless></mt:entries>
<mt:loop name="allentries" sort_by="value numeric reverse">
<mt:unless name="__counter__" gt="5"><mt:var name="__key__"></mt:unless>
</mt:loop>
<h1>Related entries:</h1>
<mt:entryid setvar="thisentryid">
<mt:entries tags="$searchoptions"><mt:unless tag="entryid" eq="$thisentryid">
<mt:var name="matches" value="0">
<mt:entrytags><mt:tagname setvar="thetag"><mt:if name="tags{$thetag}"><mt:var name="matches" op="+" value="1" setvar="matches"></mt:if></mt:entrytags>
<mt:setvarblock name="theentry">
...
</mt:setvarblock>
<mt:var name="allentries{$theentry}" value="$matches">
</mt:unless></mt:entries>
<mt:loop name="allentries" sort_by="value numeric reverse">
<mt:unless name="__counter__" gt="5"><mt:var name="__key__"></mt:unless>
</mt:loop>
</mt:if>
A little explanation: in the first line, the 'tags' hash is filled with all the tags for the current entry. The second line is similar to the previous code snippet, as are most of the following lines: we grab the tags of the current entry and select entries that share one or more of the same tags. Where things get interesting is inside the mt:entries loop. A 'matches' variable is set to zero, and it is incremented by one each time one of the tags of the current entry is present in the tags hash containing the tags of the 'original' entry. Finally, we store whatever we want to display of the current entry in the 'theentry' variable, and we use this variable as the key in the 'allentries' hash, with the number of matches as the value.
Finally, we loop over this hash, in reverse numerical order by value, meaning the entries with most matches come first.
This will give us a nice list of entries that share tags with the current entry, which is exactly what we need.
Only one problem remains: what if a newer entry is written that has many tags in common with one or more older entries? How can we make sure these entries receive an update so their 'Related entries' list is brought up to date? Republishing the entire blog is a possibility, but not really practical if you have a large blog.
A better way is to use Endevver's Related Entries plugin, which automatically republishes all entries that share a tag with an entry that is being saved or published. If you have many entries sharing similar tags it could still be a drain on resources, but it is better than doing a full republish! And of course you can use background publishing.




Leave a comment