Tags

Summary: How to have tags (like Flickr)
Version:
Prerequisites: PmWiki version: 2.2.56
Status:
Maintainer: Michael Vonrueden
Discussion: Tags-Talk
Users: +2 (View / Edit)

How to re-create or update a Tags page

It may not be obvious to everyone (it wasn't to me, Thomas Tempelmann? January 24, 2011, at 07:18 AM): After deleting or modifying a Tags page, or after changing this script, you want to recreate the Tags page. In order to accomplish this, a tag link on a page listing that tag has to be followed - that will apparently scan all pages, thereby recreating the Page.

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

oh, by the way: tags.php downloads as an RTF file, not plain text. tamouse August 24, 2010, at 10:12 AM

Gack! Why? --Fatman? October 01, 2010, at 09:11 AM
Fixed. rikblok? October 01, 2010, at 01:36 PM

For some reason, I was getting an empty tag in the listtags, with a value that was astronomical. I changed the line in listtags from:

  if ($tag!="0")

to

  if ($tag!="0" && !empty($tag))

Thanks!! This is a great feature!! Just what I was looking for. :) tamouse August 24, 2010, at 10:11 AM


Hello, this is a nice feature, but is there a way to get rid of the html warnings about unescaped & or unknown entity "&..."? I always get the warning because the generated code looks like this: <div class='tags'><a href="?action=tags&amp;tag=AAA&PHPSESSID=long number">AAA</a>... The problem is the amp before PHPSESSID. It should be replaced by "& amp;" but I did not find where. Can u help? asc, 20090513

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)

I've created a new version of the tags.php which includes several of the pages mentioned above plus some additional ones described here:

  • there's now a tags-hide command which declares tags that won't be shown on the page.
  • the listtags command now accepts a parameter showselected which highlights the tags for the current page (the style class .listtag and .listtagavailable can be used for different styles)
  • the listgrouptags now also supports the showselected parameter.
  • the limitiation of the font size can be set using the parameter $tags_limit_size (0 = no limitation)
  • the title for the listed tag pages can be customised using the $tags_title_prefix variable now.
  • an empty tag shouldn't come up anymore as of now a match is being checked (no match = no tags)

tags-patched.phpΔ

-- Daniel Kasmeroglu (May 22, 2011)

Versions

  • 20180527 Update for PHP 5 and 7, add $RecipeInfo (Petko).
  • 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.

Contributors

Michael Vonrueden


Hi, when i try to include this in my wiki i get the following error:

Warning: Cannot modify header information - headers already sent by (output started at /f5/1rpm/public/cookbook/tags.php:2) in /f5/1rpm/public/pmwiki.php on line 1092

what could this be? 20/01/2010


Hello ... I am wondering if its possible use the Tags into a (:pagelist:) to display all the pages with some specific tag (or tags)? Any clue?

Have a nice day.
eseval July 24, 2011, at 09:21 AM


Hello folks. I finally figured out how to solve my problem. The answer was in front of me all the time. Pretty easy really. Check this:

(:Tags:tag1,tag2,tag3:)(:tags-hide tag1,tag2,tag3:)

... and voilá. I have a PVT named Tags to use in my (:pagelist:).

Have a nice day.
eseval October 20, 2011, at 11:58 AM


New issue on Tags-Talk page. -- tamouse October 08, 2011, at 05:48 PM