Recent Changes - Search:

Cookbook

PmWiki

pmwiki.org

Tags

Summary: How to have tags (like Flickr)
Version:
Prerequisites: PmWiki version: 2.0.1
Status:
Maintainer: Michael Vonrueden

Question

Ever wanted to have tags like used in flickr in wiki pages

Answer

Here is a first step to integrate this into pmwiki.

Add the following line to local/config.php

  include_once('cookbook/tags.php');  

Download tags.phpΔ

Notes and Comments

Hallo! This is a very useful feature, one question: Is there any way displaying the "titles" instead of the pagenames when I klick on a tag?

How do you make display articles associated with the tag? I see it works on your artist page, but not on mine. If I click on the tag listed below, a new page is created in a new group called Test. Thanks for ant help. Cool feature, I hope I'll get it work

Uuups, i uploaded a wrong version of the script, the $tags_prefix variable have to be set as global in function function HandleTags(). Sorry for that... will update the script on this page. Please see the updated Usage section below, too. 08 Sept 2005 12:52 CET
Thanks for quick reply. I'll wait for the updated version as it is not clear to me what I have change and how. lk 13:55

This is a really great script. My wishlist for the next version:

  • A way to put a limit on how big the font size can get in the tag list. The script, as I understand it, simply determines the size of the font based on the # of instances of that tag. So if you have a tag word that's been used many many times, that word in the tag list becomes very very large.
  • Improvements in the regex parser --- I've notices some oddities in usage like what happens when you tag your page "dog" vs. "dogs". Also, if you tag any of your pages "tag" or "tags", it breaks the wikigroup header link back to the Tags home page.

I don't use flickr so I'm not shure what this script is exactly doing. By looking on the example side and the code it seems like Categories with weighted output? - Schlaefer September 07, 2005, at 02:00 AM

Yes, it is a kind of categories. The difference are the "on the fly" approach of the keywords or tags and espicially the weighted output. The script was developed for easier editing in the context of our artist-directory, where especially novice-wiki-editors edit their pages. Michael

How can I make the script support chinese tags? Thanks. Moyer 2005-11-19

ATM the space between keywords and words in a tag that consists of multiple words are the same. What can I do to make (:listtags:) produce keywors separated by comma or additional empty spaces? -- Torsten May 25, 2007, at 10:23 AM


I have a couple of small changes/fixes to the tags script:

1) The list of tags on a page has a comma even after the last tag in the list. I changed the Tagger() function as follows to fix it:

 
  function Tagger($i)
  {
      global $action;
      $tags = explode(",",$i);
      $output ="<div class='tags'>";
      $prefix = '';
      foreach ($tags as $tag)
      {
          $tag=trim($tag);
          $output=$output.$prefix.'<a href="'.$ScriptUrl.'?action=tags&amp;tag='.$tag.'">'.$tag.'</a>';
          $prefix = ', ';
      }
      return $output."</div>";
  }

2) The HandleTags() function also lists pages where the input tag is a substring of one of the tags for a page. For example, if page A has a tag photography and page B has a tag graph, clicking on the graph tag in the (:listtags:) page lists both pages A and B. I changed the HandleTags() function as follows to fix this problem:

 
  function HandleTags()
  {
      global $tags_prefix;	
      $taggedPages;
      $tag = $_GET["tag"];
      $pagelist = ListPages();
      foreach ($pagelist as $pagename)
      {
            $page=ReadPage($pagename, READPAGE_CURRENT);
            $matched_tags=preg_match('/\\(:tags\\s(.*?):\\)/i',$page['text'], $matches);
            if(0 != $matched_tags)
            {
                  $rawtags = explode(",", $matches[1]);
                  foreach($rawtags as $value)
                  {
                        if(0 == strcasecmp($tag, trim($value)))
                        {
                              $name=explode(".",$page['name']);
                              $taggedPages=$taggedPages.'*[['.$name[1].'->'.$pagename.']] ';
                              $taggedPages=$taggedPages." \n";
                              break 1;
                        }
                  }
            }
      }
      $text="Sites that are tagged with: @@".$tag."@@ \n\n";
      $page = array("text"=>$text.$taggedPages);
      $sitename=$tags_prefix.".".ucfirst(str_replace(" ","",$tag));
      WritePage($sitename,$page);
      Redirect($sitename);
  }

Thanks --KaushikSridharan January 15, 2006, at 04:21 AM

How would I go about changing the script so that the generated tag pages display the page name spaced not all bunched up? - Jonathan Cutrer

In the HandleTags function, try adding the AsSpaced function ... replace this line:
       $taggedPages=$taggedPages.'*[['.$name[1].'->'.$pagename.']] '; 
... with this:
       $taggedPages=$taggedPages.'*[['.AsSpaced($name[1]).'->'.$pagename.']] '; 
- Sim' (May 14, 2006)

I ran into the problem of font size being extremely hugh in the tag cloud for tags that had many pages. I hacked around in tags.php and came up with the following solution in the ListTags() function. foreach ($tags as $tag=>$value) { if($tag!="0") if ($value > 25) {$correctedvalue = 25;} else {$correctedvalue = $value;} $output=$output.'<span style="background-color:lightwhite;font-size:'.($correctedvalue+10).'px;font-weight:'.($value+500).'"> <a href="'.$ScriptUrl.'?action=tags&amp;tag='.$tag.'">'.$tag.'</a></span> '; }

I wanted the (:listtags:) markup to retrieve the tags in alphabetical order, so I changed a portion of the ListTags() function to:

	$output;
	ksort ($tags);
	foreach ($tags as $tag=>$value)

-- Angela Kille (April 6, 2006)

I made a few minor adjustments to tags.php for a wiki a friend of mine is running, which I thought I'd share back here.

1) If you make heavy use of the title functionality of PMWiki, you might want the tag pages to display their titles rather than filenames. If so, you can change the two assignments of $taggedpages in the HandleTags() function:

                  $taggedPages=$taggedPages.'*[['.$pagename.'|+]] ';
                  $taggedPages=$taggedPages." \n"; 

2) The current version doesn't work with tags that include apostrophes or other escaped characters. To fix that, you can make two changes to HandleTags(). First, after the $_GET line, add:

$tag = stripslashes($tag);

and replace the line beginning with $sitename with:

$sitename=$tags_prefix.".".ucfirst(ereg_replace("[\'\ ]","",$tag));

(adding whatever other escaped characters you want to allow into the regex).

3) Finally, I threw together a pretty hacky way to limit the tag list to only tags that appear within a specified group. Add the following near the top, under the other Markup lines:

Markup("listgrouptags", "directives", '/\\(:listgrouptags\\s(.*?):\\)/ei', "ListGroupTags('$1')");

And add the following additional function at the bottom:

function ListGroupTags($i)
{
  $tags;
  $group = ereg_replace("/[^a-z\-_ \d]/i", "", $i);
  $pagelist = ListPages("/^$group.*/");
  foreach ($pagelist as $pagename)
    {
      $page=ReadPage($pagename, READPAGE_CURRENT);
      $matched_tags=preg_match('/\\(:tags\\s(.*?):\\)/ei',$page['text'], $matches);
      {
	$rawtags= explode(",",substr($matches[0],6,-2));
	foreach($rawtags as $value)
	  $tags[ucfirst(trim($value))]+=1;
	ksort($tags);
      }
    }
  $output;
  if (sizeof($tags) != 0) {
    foreach ($tags as $tag=>$value)
      {
	if($tag!="0")
	  $output=$output.'<span style="background-color:lightwhite;font-size:'.($value+10).'px;font-weight:'.($value+500).'">
 <a href="'.$ScriptUrl.'?action=tags&amp;tag='.$tag.'">'.$tag.'</a></span> ';
      }
  }
  return $output;
}

The syntax is (:listgrouptags GroupName:); I may go back and put together a "proper" version of this that accepts more options and fails more gracefully later.

-- Joshua Hall-Bachner (April 23, 2007)

Versions

2005-08-31 tags.php Initial Startup v1.0

Usage

This script enables tagged sites like in flickr. Insert tags into the wikis with this markup:

    (:tags keyword, Keyword, etc. :)
  • Retrieve all Tags with the markup
    (:listtags:)
  • The function HandleTags() will generate Temporary Sites in the style of Tag.Keyword. By default the $tags_prefix is set to "Tags". Generated Sites will appear like Tags.MyTag. You have to change this inside the script for your own purposes.
  • The Tags on a page (see (:tags keyword, Keyword, etc. :)) are nested in a <div> tag. You can style this with the CSS-Class "tags" (Line 37).
  • The Tags-List (see (:listtags:)) is layouted with an inline style attribute due to the weighted output (font-size attribute). To change this modify line 92 in the script directly.

See Also

See the recipe in action at the artistnet site www.crossoverarts.de

Contributors

Michael Vonrueden


Just wanted to say, that this is an awesome tool. Thanks a lot. -- Torsten May 25, 2007, at 04:55 AM

Edit - History - Print - Recent Changes - Search
Page last modified on October 09, 2007, at 09:42 PM