DokuWiki

It's better when it's simple

User Tools

Site Tools


plugin:cloud:discussion_old

Old Discussion of the Cloud Plugin

Using Cloud as Navigation in Template Monobook:
If you want to use the Cloud in the Navigation box, then the cloud has not the normal CSS layout. To change this to the normal layout, you have to duplicate in the Cloud-CSS the code:

div.dokuwiki div#cloud a.cloud1 { font-size: 10px; color: #D3E0F5; }
div.dokuwiki div#cloud a.cloud2 { font-size: 12px; color: #AEC4E5; }
div.dokuwiki div#cloud a.cloud3 { font-size: 14px; color: #88A9DB; }
div.dokuwiki div#cloud a.cloud4 { font-size: 16px; color: #4A7AC2; }
div.dokuwiki div#cloud a.cloud5 { font-size: 18px; color: #003F9E; }

div.dokuwiki div#cloud a.cloud1_tag1 { font-size: 10px; color: #CEF0D0; }
div.dokuwiki div#cloud a.cloud2_tag1 { font-size: 12px; color: #AEE5B1; }
div.dokuwiki div#cloud a.cloud3_tag1 { font-size: 14px; color: #88DB8C; }
div.dokuwiki div#cloud a.cloud4_tag1 { font-size: 16px; color: #4AC250; }
div.dokuwiki div#cloud a.cloud5_tag1 { font-size: 18px; color: #009E08; }

div.dokuwiki div#cloud a.cloud1_tag2 { font-size: 10px; color: #F0CED7; }
div.dokuwiki div#cloud a.cloud2_tag2 { font-size: 12px; color: #E5AEBC; }
div.dokuwiki div#cloud a.cloud3_tag2 { font-size: 14px; color: #DB889D; }
div.dokuwiki div#cloud a.cloud4_tag2 { font-size: 16px; color: #C24A68; }
div.dokuwiki div#cloud a.cloud5_tag2 { font-size: 18px; color: #9E0028; }

But you have to replace

div.dokuwiki div#cloud

by

div.portlet div#cloud

. Refresh the visted page with CTRL+F5
Alex, March 2009


Doesn't seem to work with RC-2009-01-30 :(

One issue is not handled by this plugin: different localizations. Or maybe did I miss it? How would a en:xxxx namespace tag list being shown on en:xxxx pages, while parallel fr:yyyy tags shown on fr:yyyyy pages using the same website? thanks for enlightening. Stephanie Sep/15/08



Wow! That is so cool-Thankyou-georgie 2007-1-2

It doesn't do well with contractions (i.e. “doesn't,” “isn't,” etc.), and it looks bad to have my word cloud have “doesn” (sic) in it. I'll just blacklist common contractions for now… -[Unregistered DokuWiki fan =D]
This is due to the way DokuWiki splits the text into chunks for the word index. I can't change that. — Esther Brunner 2007-01-10 23:42
Ah, okay. No problem; this is a cool plugin :-)
Hello, we used the Tagcloud on our internal wiki but the pages took about a second to generate and used 100% of the CPU capacity. Do you have an idea for and improvement? The best improvement we found until now was to disable the cloud …

Taz 20-03-08

Could you please give some numbers on how many pages doe you have in your wiki? — Michael Klier 2008/04/19 12:12



Hello,

Thank you for this plugin, it's visually very impressive, and seems to render what haunts my mind !
Is it possible to restrict the words to those found in certain namespaces ?
We have a unique wiki, but some namespaces are given public Intranet access, and others are for our team's internal docs and hidden to others.
Cloud shows all words, which leads to page access denial out of our team.
BTW, maybe we should run two well separated wikis…

Pascal 11-04-08

Hmmm, I'll have to think about it ;-). — Michael Klier 2008/04/19 12:12
Great ! I hope it can be done. Is every indexed word related to the list of documents it appears into ? And how expensive would it be ? Thanx anyway, — Pascal 2008/04/20 00:23 GMT

Tag clouds don't work for my (with newest DokuWiki RC). I must changed code from using backlinks to: $link = wl($id, array('do'⇒'showtag', 'tag'⇒$word));

Fixed! — Michael Klier 2008/05/10 13:39

If anyone has the same issue I had, whereby the list of tags appear but don't have any styling (Varying sizes and shades), update your cloud tag and your tag cloud from your plugin manager and then refresh the page the cloud is on. Graham Macleod PS Roland, that script is very handy. Thanks. Works a treat. You should maybe re-emphasise that each word must go on it's own line. Or perhaps force it some way.


Just a thought, but instead of adding loads of words into stopwords.txt, how about just adding the words you'd like into the a wordcloud list; this list would then be the one shown, kind of like a reverse version of what is already available. Can this be implemented? Chris 30/6/08

OH I would like that too! Is there a way of doing this? Cat 09/09/09

Stopwords for tagcloud

The stopwords feature doesn't work for TAGCLOUD, here is a small patch that fixes it :

--- syntax.php.orig     2008-03-18 14:55:10.000000000 +0100
+++ syntax.php  2008-03-18 15:04:03.000000000 +0100
@@ -101,13 +101,7 @@
     global $conf;
 
     // load stopwords
-    $swfile   = DOKU_INC.'inc/lang/'.$conf['lang'].'/stopwords.txt';
-    if (@file_exists($swfile)) $stopwords = file($swfile);
-    else $stopwords = array();
-
-    // load extra local stopwords
-    $swfile = DOKU_CONF.'stopwords.txt';
-    if (@file_exists($swfile)) $stopwords = array_merge($stopwords, file($swfile));
+    $stopwords = $this->_getStopWords();
 
     $cloud = array();
 
@@ -150,6 +144,20 @@
     }
   }
 
+  function _getStopWords()
+  {
+    // load stopwords
+    $swfile   = DOKU_INC.'inc/lang/'.$conf['lang'].'/stopwords.txt';
+    if (@file_exists($swfile)) $stopwords = file($swfile);
+    else $stopwords = array();
+
+    // load extra local stopwords
+    $swfile = DOKU_CONF.'stopwords.txt';
+    if (@file_exists($swfile)) $stopwords = array_merge($stopwords, file($swfile));
+
+    return $stopwords;
+  }
+
   /**
    * Returns the sorted tag cloud array
    */
@@ -160,6 +168,13 @@
       $cloud[$key] = count($value);
     }
 
+    // filter stopwords
+    foreach($this->_getStopWords() as $w)
+    {
+      $w = trim($w);
+      unset($cloud[$w]);
+    }
+
     return $this->_sortCloud($cloud, $num, $min, $max);
   }

Hope that could help someone.

Stéphane Gully

Is this needed? Could someone please give some feedback why one wants to use the stopwords feature in the tag cloud context? — Michael Klier 2008/04/19 12:12
I think this wouldn't be logical for the tag cloud functionality. Though, it is definitely required for the word cloud feature. This way I am able to filter out numbers (ie. 2008 06 2 22 25 8-)) from the word cloud. — Mischa The Evil 2008/06/02 22:25

Namespace clouds

TommyWang 09-05-08

I made a small modification to this plugin and added the ability to limit the word cloud and tag cloud to specific namespaces. When clicking the word cloud, it will restrict the search to the namespace specified. The tag cloud, however, will still display a full backlinks list. Its only been casually tested, so YMMV. I had to change the syntax up a little bit to allow for namespaces. So, now its used:

{{cloud>[ns]#[num]}}
{{tagcloud>[ns]#[num]}}

Where [ns] and [num] are both optional. default ns is *, and default num is still 50. ns shortcuts (.,:,*) are resolved. If using all defaults, simply {{cloud>}} will do.

Here's the patch (use -p1 to apply):

diff -Naur cloud/syntax.php cloud2/syntax.php
--- cloud/syntax.php	2008-04-19 05:26:36.000000000 -0500
+++ cloud2/syntax.php	2008-05-09 20:20:11.190002200 -0500
@@ -32,24 +32,37 @@
   function getSort(){ return 98; }
 
   function connectTo($mode) {
-    $this->Lexer->addSpecialPattern('~~\w*?CLOUD.*?~~', $mode, 'plugin_cloud');
+    $this->Lexer->addSpecialPattern('{{\w*?cloud>.*?}}', $mode, 'plugin_cloud');
   }
 
   function handle($match, $state, $pos, &$handler){
+    global $ID;
+
     $match = substr($match, 2, -2); // strip markup
-    if (substr($match, 0, 3) == 'TAG') $type = 'tag';
-    else $type = 'word';
-    
-    list($junk, $num) = explode(':', $match, 2);
+    if (substr($match, 0, 3) == 'tag') {
+      $match = substr($match, 9);
+      $type = 'tag';
+    }
+    else {
+      $match = substr($match, 6);
+      $type = 'word';
+    }
+
+    list($ns, $num) = explode('#', $match, 2);
+
+    if (($ns == '*') || ($ns == ':')) $ns = '';
+    elseif ($ns == '.') $ns = getNS($ID);
+    else $ns = cleanID($ns);
+
     if (!is_numeric($num)) $num = 50;
 
-    return array($type, $num);
+    return array($type, $ns, $num);
   }            
 
   function render($mode, &$renderer, $data){
     global $conf;
 
-    list($type, $num) = $data;
+    list($type, $ns, $num) = $data;
 
     if ($mode == 'xhtml'){
 
@@ -58,9 +71,9 @@
           msg('The Tag Plugin must be installed to display tag clouds.', -1);
           return false;
         }
-        $cloud = $this->_getTagCloud($num, $min, $max, $tag);
+        $cloud = $this->_getTagCloud($ns, $num, $min, $max, $tag);
       } else {
-        $cloud = $this->_getWordCloud($num, $min, $max);
+        $cloud = $this->_getWordCloud($ns, $num, $min, $max);
       }
       if (!is_array($cloud) || empty($cloud)) return false;
       $delta = ($max-$min)/16;
@@ -93,10 +106,16 @@
           $class .= ($exists ? '_tag1' : '_tag2');
         } else {
           if($conf['userewrite'] == 2) {
+            if ($ns == '')
             $link = wl($word, array('do'=>'search', 'id'=>$word));
+            else
+              $link = wl($word, array('do'=>'search', 'id'=>"$word@$ns"));
             $title = $size;
           } else {
+            if ($ns == '')
             $link = wl($word, 'do=search');
+            else
+              $link = wl("$word@$ns", 'do=search');
             $title = $size;
           }
         }
@@ -112,7 +131,7 @@
   /**
    * Returns the sorted word cloud array
    */
-  function _getWordCloud($num, &$min, &$max){
+  function _getWordCloud($ns, $num, &$min, &$max){
     global $conf;
 
     // load stopwords
@@ -128,6 +147,7 @@
 
     if (@file_exists($conf['indexdir'].'/page.idx')){ // new word-lenght based index
       require_once(DOKU_INC.'inc/indexer.php');
+      $page_idx = idx_getIndex('page','');
 
       $n = 2; // minimum word length
       $lengths = idx_indexLengths($n);
@@ -135,23 +155,19 @@
         $idx      = idx_getIndex('i', $len);
         $word_idx = idx_getIndex('w', $len);
 
-        $this->_addWordsToCloud($cloud, $idx, $word_idx, $stopwords);
+        $this->_addWordsToCloud($cloud, $ns, $idx, $word_idx, $page_idx, $stopwords);
       }
 
-    } else {                                          // old index
-      $idx      = file($conf['cachedir'].'/index.idx');
-      $word_idx = file($conf['cachedir'].'/word.idx');
-      
-      $this->_addWordsToCloud($cloud, $idx, $word_idx, $stopwords);
     }
 
+    if (empty($cloud)) return $cloud;
     return $this->_sortCloud($cloud, $num, $min, $max);
   }
 
   /**
    * Adds all words in given index as $word => $freq to $cloud array
    */
-  function _addWordsToCloud(&$cloud, $idx, $word_idx, &$stopwords){
+  function _addWordsToCloud(&$cloud, $ns, $idx, $word_idx, $page_idx, &$stopwords){
     $wcount = count($word_idx);
 
     // collect the frequency of the words
@@ -160,7 +176,17 @@
       if (!is_int(array_search("$key\n", $stopwords))){
         $value = explode(':', $idx[$i]);
         if (!trim($value[0])) continue;
+        if ($ns == '')
         $cloud[$key] = count($value);
+        else
+        {
+          foreach ($value as $v)
+          {
+            list($p,$c) = explode('*', $v);
+            if (substr($page_idx[$p], 0, strlen($ns)) == $ns)
+              $cloud[$key]++;
+          }
+        }
       }
     }
   }
@@ -168,13 +194,22 @@
   /**
    * Returns the sorted tag cloud array
    */
-  function _getTagCloud($num, &$min, &$max, &$tag){
+  function _getTagCloud($ns, $num, &$min, &$max, &$tag){
     $cloud = array();
     foreach ($tag->tag_idx as $key => $value){
       if (!is_array($value) || empty($value) || (!trim($value[0]))) continue;
+      if ($ns == '')
       $cloud[$key] = count($value);
+      else
+      {
+        foreach ($value as $idx){
+          if (substr($tag->page_idx[$idx], 0, strlen($ns)) == $ns)
+            $cloud[$key]++;
+        }
+      }
     }
 
+    if (empty($cloud)) return $cloud;
     return $this->_sortCloud($cloud, $num, $min, $max);
   }

This is a new patch for cloud plugin update 2008-07-10:
jayjay 2008/07/16 14:47 CET - updated 2008/08/20 16:18 CET (thanks pan One!)

diff U3 syntax.bak.php syntax.php
--- syntax.bak.php	Wed Jul 16 09:20:49 2008
+++ syntax.php	Wed Jul 16 14:08:52 2008
@@ -32,24 +32,37 @@
     function getSort() { return 98; }
 
     function connectTo($mode) {
-        $this->Lexer->addSpecialPattern('~~\w*?CLOUD.*?~~', $mode, 'plugin_cloud');
+        $this->Lexer->addSpecialPattern('{{\w*?cloud>.*?}}', $mode, 'plugin_cloud');
     }
 
     function handle($match, $state, $pos, &$handler) {
+    global $ID;
+
         $match = substr($match, 2, -2); // strip markup
-        if (substr($match, 0, 3) == 'TAG') $type = 'tag';
-        else $type = 'word';
+    if (substr($match, 0, 3) == 'tag') {
+      $match = substr($match, 9);
+      $type = 'tag';
+    }
+    else {
+      $match = substr($match, 6);
+      $type = 'word';
+    }
+
+    list($ns, $num) = explode('#', $match, 2);
 
-        list($junk, $num) = explode(':', $match, 2);
-        if (!is_numeric($num)) $num = 50;
+    if (($ns == '*') || ($ns == ':')) $ns = '';
+    elseif ($ns == '.') $ns = getNS($ID);
+    else $ns = cleanID($ns);
 
-        return array($type, $num);
+        if (!is_numeric($num)) $num = 20;
+
+        return array($type, $ns, $num);
     }            
 
     function render($mode, &$renderer, $data) {
         global $conf;
 
-        list($type, $num) = $data;
+        list($type, $ns, $num) = $data;
 
         if ($mode == 'xhtml') {
 
@@ -58,9 +71,9 @@
                     msg('The Tag Plugin must be installed to display tag clouds.', -1);
                     return false;
                 }
-                $cloud = $this->_getTagCloud($num, $min, $max, $tag);
+                $cloud = $this->_getTagCloud($ns, $num, $min, $max, $tag);
             } else {
-                $cloud = $this->_getWordCloud($num, $min, $max);
+                $cloud = $this->_getWordCloud($ns, $num, $min, $max);
             }
             if (!is_array($cloud) || empty($cloud)) return false;
             $delta = ($max-$min)/16;
@@ -89,10 +102,16 @@
                     $class .= ($exists ? '_tag1' : '_tag2');
                 } else {
                     if($conf['userewrite'] == 2) {
-                        $link = wl($word, array('do'=>'search', 'id'=>$word));
+                        if ($ns == '')
+						$link = wl($word, array('do'=>'search', 'id'=>$word));
+						else
+						$link = wl($word, array('do'=>'search', 'id'=>"$word@$ns"));
                         $title = $size;
                     } else {
-                        $link = wl($word, 'do=search');
+                        if ($ns == '')
+						$link = wl($word, 'do=search');
+						else
+						$link = wl("$word@$ns", 'do=search');
                         $title = $size;
                     }
                 }
@@ -108,7 +127,7 @@
     /**
      * Returns the sorted word cloud array
      */
-    function _getWordCloud($num, &$min, &$max) {
+    function _getWordCloud($ns, $num, &$min, &$max){
         global $conf;
 
         // load stopwords
@@ -124,6 +143,7 @@
 
         if (@file_exists($conf['indexdir'].'/page.idx')) { // new word-lenght based index
             require_once(DOKU_INC.'inc/indexer.php');
+			$page_idx = idx_getIndex('page','');
 
             $n = 2; // minimum word length
             $lengths = idx_indexLengths($n);
@@ -131,23 +151,19 @@
                 $idx      = idx_getIndex('i', $len);
                 $word_idx = idx_getIndex('w', $len);
 
-                $this->_addWordsToCloud($cloud, $idx, $word_idx, $stopwords);
+                $this->_addWordsToCloud($cloud, $ns, $idx, $word_idx, $page_idx, $stopwords);
             }
 
-        } else {                                          // old index
-            $idx      = file($conf['cachedir'].'/index.idx');
-            $word_idx = file($conf['cachedir'].'/word.idx');
-
-            $this->_addWordsToCloud($cloud, $idx, $word_idx, $stopwords);
         }
 
-        return $this->_sortCloud($cloud, $num, $min, $max);
+        if (empty($cloud)) return $cloud;
+		return $this->_sortCloud($cloud, $num, $min, $max);
     }
 
     /**
      * Adds all words in given index as $word => $freq to $cloud array
      */
-    function _addWordsToCloud(&$cloud, $idx, $word_idx, &$stopwords) {
+    function _addWordsToCloud(&$cloud, $ns, $idx, $word_idx, $page_idx, &$stopwords){
         $wcount = count($word_idx);
 
         // collect the frequency of the words
@@ -156,22 +172,41 @@
             if (!is_int(array_search("$key\n", $stopwords))) {
                 $value = explode(':', $idx[$i]);
                 if (!trim($value[0])) continue;
+				if ($ns == '')
                 $cloud[$key] = count($value);
-            }
+		        else
+		        {
+		          foreach ($value as $v)
+					{
+		            list($p,$c) = explode('*', $v);
+		            if (substr($page_idx[$p], 0, strlen($ns)) == $ns)
+		              $cloud[$key]++;
+					}
+		        }
+			}
         }
     }
 
     /**
      * Returns the sorted tag cloud array
      */
-    function _getTagCloud($num, &$min, &$max, &$tag) {
+    function _getTagCloud($ns, $num, &$min, &$max, &$tag){
         $cloud = array();
         foreach ($tag->topic_idx as $key => $value) {
             if (!is_array($value) || empty($value) || (!trim($value[0]))) continue;
+			if ($ns == '')
             $cloud[$key] = count($value);
-        }
+			else
+			{
+				foreach ($value as $idx){
+				  if (substr($idx, 0, strlen($ns)) == $ns)
+					$cloud[$key]++;
+				}
+			}
+		}
 
-        return $this->_sortCloud($cloud, $num, $min, $max);
+        if (empty($cloud)) return $cloud;
+		return $this->_sortCloud($cloud, $num, $min, $max);
     }
 
     /**
Thank you Tommy !

It works quite well for me, and does what I needed.

If it's easy to do, the new syntax could be extended to accept several namespaces (something like ns1|ns2 ?) or to exclude some ns, or better, to accept a regular expression.

But don't do it just for me, I'm glad with this version !

What happens next ? Even if what you did satisfies Michael, how can he include it in future versions, since the syntax has changed ? Are we condemned to an everlasting duality of cloud and cloud2 ?

Thanks again, —
Pascal 2008/05/16 00:27 GMT

I like the approach by TommyWang and I believe namespace clouds are very useful. Michael, is there any chance that (part of) TommyWang's code finds its way to your cloud plugin?
jayjay 2008/07/15 23:05 CET



There is no page_idx in the tag plugin (anymore). The line:

    if (substr($tag->page_idx[$idx], 0, strlen($ns)) == $ns)

should read:

    if (substr($idx, 0, strlen($ns)) == $ns)

I really hope they will take over this patch into official version. The maintenance is getting cumbersome. — pan One 2008/08/17

Thanks pan One! I haven't used tag clouds yet (will do very shortly) so you beat me to it :-) Anyway, I changed the above 2008-07-10 diff.
jayjay 2008-08-20 16:19 CET

\\Any chance there will be an update for the latest greatest version of the cloud plugin? Or at least downloads of older versions to apply this patch to?
Kyle 2009-05-05

Admin Page

Version 1.0

An admin-page for adding stopwords would be nice. I started one (my first php script, so feel free to optimize :-). Copy this as admin.php in your plugins/cloud/ directory.

<?php
 
/*
 * stopwords management
 */
if (!defined('DOKU_INC'))
	define('DOKU_INC', realpath(dirname(__FILE__) . '/../../') . '/');
if (!defined('DOKU_PLUGIN'))
	define('DOKU_PLUGIN', DOKU_INC . 'lib/plugins/');
require_once (DOKU_PLUGIN . 'admin.php');
 
class admin_plugin_cloud extends DokuWiki_Admin_Plugin {
 
	/**
	 * function constructor
	 */
	function admin_plugin_cloud() {
		// enable direct access to language strings
		$this->setupLocale();
	}
 
	/**
	 * return some info
	 */
	function getInfo() {
		return array (
			'author' => '...',
			'email' => '...',
			'date' => '2008-05-16',
			'name' => 'Stopwords management',
			'desc' => 'Manage stopwords for the cloud plugin',
			'url' => '...',	
		);
	}
 
	function handle() {
	}
 
    function getMenuText($language) {
        return 'Stopwords management';
    }
 
	function html() {
		global $ID;
		$swfile = DOKU_CONF . 'stopwords.txt';
		if($_REQUEST['stopwords']) {
			ptln(' SAVED <br>');
			$sw = $_REQUEST['stopwords'];
			$swarray = explode( "\n"  , $sw );
			$out = "";
			foreach($swarray as $v) {
				$v = trim($v);
				if(strlen($v)>0) {
		    		$out = $v."\n".$out;
				}
	    	}
   			io_saveFile( $swfile, $out);
		}
 
		if (@ file_exists($swfile)) {
			$stopwords = io_readfile($swfile);
		} else {
			$stopwords = "";
		}
		ptln('<form name="frm" action="" method="post">');
		ptln('<textarea name="stopwords" cols="40" rows="25"">');
		ptln($stopwords);
		ptln('</textarea>');
		ptln('      <input type="submit" value="save" class="button" /></td>');
		ptln('</form>');
	}
}
?>

Roland 2008-5-16

Version 1.1

Kite [at] Puzzlers [dot] org wrote this revision/expansion of the Admin module.

  • A list of 200 words is available to pick your kill list from. Java script updates your working list.
  • Killwords are sorted when they are returned to the UI so they are easier to remove.
  • UI Text is exported to a language file for translation.
  • July 8, 2008 – I updated the admin.php and the style.css files to fix some compatibility issues with IE JavaScript, DHTML, and styles. Thanks to kerry chris for the comments and suggestions.

This is inc/plugins/cloud/admin.php

<?php
 
/*
 * stopwords management
 */
if (!defined('DOKU_INC'))
	define('DOKU_INC', realpath(dirname(__FILE__) . '/../../') . '/');
if (!defined('DOKU_PLUGIN'))
	define('DOKU_PLUGIN', DOKU_INC . 'lib/plugins/');
require_once (DOKU_PLUGIN . 'admin.php');
 
class admin_plugin_cloud extends DokuWiki_Admin_Plugin {
 
	/**
	 * function constructor
	 */
	function admin_plugin_cloud() {
		// enable direct access to language strings
		$this->setupLocale();
	}
 
	/**
	 * return some info
	 */
	function getInfo() {
		return array (
			'author' => 'Kite',
			'email' => 'kite@puzzlers.org',
			'date' => '2008-07-11',
			'name' => 'Stopwords management',
			'desc' => 'Manage stopwords for the cloud plugin',
			'url' => 'http://www.dokuwiki.org/plugin:cloud',	
		);
	}
 
	function handle() {
	}
 
    function getMenuText($language) {
        return $this->getLang('Admin_MenuText');  //'Stopwords management';
    }
 
	function stopwords_fn() {
		return DOKU_CONF . 'stopwords.txt';
	}
 
	function save_stopwords() {
		//ptln('<!-- $_REQUEST = ' . print_r($_REQUEST, true) . ' -->');
		//ptln('<!-- $_POST = ' . print_r($_POST, true) . ' -->');
		if($_REQUEST['stopwords']) {
			$sw = $_REQUEST['stopwords'];
			$swarray = explode( "\n"  , $sw );
			$out = "";
			foreach($swarray as $v) {
				$v = trim($v);
				if(strlen($v)>0) {
					$out = $v."\n".$out;
				}
			}
			io_saveFile( $this->stopwords_fn(), $out);
			return $this->getLang('Admin_SavedFile');
		}
		return '';
	}
 
	function read_stopwords() {
 
		if (@ file_exists( $this->stopwords_fn() )) {
		    //$words = explode('\n', io_readfile( $this->stopwords_fn() ));
			$words = gzfile( $this->stopwords_fn() );
			sort($words, SORT_STRING);
			return implode("", array_values($words));
		} else {
			return "";
		}	
	}
 
	function html() {
		global $ID;
		global $_POST;
 
 
		ptln("<h1>" . $this->getLang('Admin_MenuText') . "</h1>");
		ptln('<div class="cloud" id="outer">');
		//ptln('<div class="cloud" id="cloud_message">Javascript is not enabled.</div>');
		ptln('<b>' . $this->save_stopwords() . '</b></br />');
 
?>
<script language="JavaScript" type="text/javascript" charset="utf-8">
<!--//--><![CDATA[//><!--
 
	//document.getElementById( 'cloud_message' ).innerHTML = 'Javascript is enabled';
 
	function append_word( Tag, word ) {
		words = document.getElementById( Tag );
		newline = "\n";
		if( (words.value.length < 1) || (words.value.substring(1,0) == newline) ){
			//alert('The word is being appended');
			words.value = words.value + word + newline;
		} else {
			//alert('The word is being appended(2)');
			words.value = words.value + newline + word + newline;
		}
	} /* append_word */
 
	function CloudWordClicked( Tag ) {
		//alert('You clicked on tag "' + Tag + '"');
	    elem = document.getElementById( Tag );
		if( elem ) {
			//alert('The word is "' + elem.innerHTML + '"');
			//alert('The class is "' + elem.className + '"');
			if(elem.className.substring(2, 0) == '_a') {
				alert('That word was selected before');
			} else {
				elem.className = elem.className + '_a';
				//if(elem.className.substring(2, 0) == '_a') {
				//	alert('Word Selected is "' + elem.innerHTML + '"');
				//}  else {
				//	alert('The class is now "' + elem.className + '"');
				//}
 
				append_word('stopwords', elem.innerHTML );
			}
		} else {
			alert('The element was not found.');
		}
 
	} /* CloudWordClicked */
//--><!]]>
</script>
<?PHP
		ptln('<div class="cloud" id="left">');
		ptln('<form id="stopwords_form" action="' . wl($ID, array('do'=>'Admin', 'page'=>'cloud')) . '" method="POST" enctype="application/x-www-form-urlencoded">');
		//ptln('<input type="hidden" id="do" value="admin"/>');
		//ptln('<input type="hidden" id="page" value="cloud"/>');
		ptln("<fieldset class='cloud'><legend>" . $this->getLang('Admin_StopwordLabel') . "</legend>");
		ptln("<textarea id='stopwords' name='stopwords' cols='40' rows='25'>" . $this->read_stopwords() . '</textarea>');
		ptln('<br /><input type="submit" value="' .  $this->getLang('Admin_Save') . '" class="button" />');
		ptln('</fieldset></form></div> <!-- name="left" -->');
 
        ptln('<div class="cloud" id="right">');
 
		if($words = plugin_load('syntax', 'cloud')) {
			$num = 200;
			ptln("<div id='tagcloud'><fieldset class='cloud'>");
			ptln(DOKU_TAB . "<legend id='tagcloud'>" . $this->getLang('Admin_TagCloudLabel') . "</legend>");
			if (!(plugin_isdisabled('tag') || (!$tag = plugin_load('helper', 'tag'))) ) {
		        $tag_cloud = $words->_getTagCloud($num, $min, $max, $tag);
  	        }
			$this->_WordCloudDisplay($tag_cloud, $min, $max );
			ptln("</fieldset></div> <!-- id='tagcloud' -->");
 
			ptln("<div id='wordcloud'><fieldset class='cloud'>");
			ptln(DOKU_TAB . "<legend id='wordcloud'>" . $this->getLang('Admin_WordCloudLabel') . "</legend>");
        	$word_cloud = $words->_getWordCloud($num, $min, $max);
			$this->_WordCloudDisplay($word_cloud, $min, $max );
			ptln("</fieldset></div> <!-- id='wordcloud' -->");
		} else {
			ptln("<b>" . $this->getLang('Admin_WordCloudError') . "</b>");
		}			
		ptln('</div> <!-- id="right" -->');
 
		ptln('</div> <!-- id="outer" -->');
 
		$this->phpinfo();
	} // html()
 
 	function _WordCloudDisplay( $cloud, $min, $max ) {
 
		static $cloud_count = 0; 
 
		if (!$cloud || (count($cloud) == 0)) {
			ptln($this->getLang('Admin_EmptyList'));
			return;
		}
 
		$cloud_count++;
		$tag_count = 1;
		$delta = ($max-$min)/16;
 
 
		foreach ($cloud as $word => $size){
			if ($size < $min+round($delta)) $class = 'cloud1';
			elseif ($size < $min+round(2*$delta)) $class = 'cloud2';
			elseif ($size < $min+round(4*$delta)) $class = 'cloud3';
			elseif ($size < $min+round(8*$delta)) $class = 'cloud4';
			else $class = 'cloud5';
 
			if($conf['userewrite'] == 2) {
				$link = wl($word, array('do'=>'search', 'id'=>$word));
				$title = $size;
			} else {
				$link = wl($word, 'do=search');
				$title = $size;
			}
			$tag_id = "cloud_$cloud_count" . "_$tag_count";
			ptln(DOKU_TAB . DOKU_TAB . '<a class="' . $class . '" id="' . $tag_id . '" name="' . $tag_id . '" href="javascript:void(0);" onclick="CloudWordClicked( \'' . $tag_id . '\' );">' . $word .'</a>');  // .DOKU_LF 
			//ptln(DOKU_TAB . DOKU_TAB . '<a class="' . $class . '" id="' . $tag_id . '" name="' . $tag_id . '" href="javascript:CloudWordClicked( \'' . $tag_id . '\' );">' . $word .'</a>');  // .DOKU_LF
			$tag_count++; 
		} 
	}
 
	function phpinfo() {
 
	}
}

This file is inc/plugins/cloud/lang/en/lang.php and contains the UI text (there is one error message from the Syntax.php as well).

<?PHP
 
//Syntax Plugin
$lang['Tag_Plugin_Required']   = 'The Tag Plugin must be installed to display tag clouds.';
 
 
// Admin Plugin
$lang['Admin_MenuText']       = 'Stopwords management (1.1)';
$lang['Admin_Save']           = 'Save';
$lang['Admin_SavedFile']      = 'Saved your Stopwords';
$lang['Admin_StopwordLabel']  = 'Your Stopwords List';
$lang['Admin_TagCloudLabel']  = 'Available Tags';
$lang['Admin_WordCloudLabel'] = 'Available Words';
$lang['Admin_WordCloudError'] = 'Error loading the WordCloud plugin.';
$lang['Admin_EmptyList']      = 'The wordlist is empty.';

Dutch translation of the lang.php above (inc/plugins/cloud/lang/nl/lang.php)

<?PHP
 
//Syntax Plugin
$lang['Tag_Plugin_Required']   = 'De Tag Plugin moet geinstalleerd zijn om Tag cloud te tonen.';
 
// Admin Plugin
$lang['Admin_MenuText']       = 'Stopwords beheer';
$lang['Admin_Save']           = 'Opslaan';
$lang['Admin_SavedFile']      = 'Stopwords zijn opgeslagen';
$lang['Admin_StopwordLabel']  = 'Your Stopwords List';
$lang['Admin_TagCloudLabel']  = 'Beschikare Tags';
$lang['Admin_WordCloudLabel'] = 'Beschikare  Words';
$lang['Admin_WordCloudError'] = 'Fout tijdens laden van de WordCloud plugin.';
$lang['Admin_EmptyList']      = 'De stopwoorden lijst is leeg.';
?> 

This file is updated into inc/plugins/cloud/style.css. The *_a styles are used for words you've put into the killword list. I haven't done a lot with this, but I like seeing which words are added; its just a color change in the styles.

July 11/2008 – Kite altered the sample CSS since it was assuming an extra DIV that the plugin itself does not supply.

/*div.dokuwiki div.page */
div.cloud { 
	margin-bottom: 1em; 
	clear: both;
	float:left;
}
 
/*div.dokuwiki div.page */
div.cloud a { 
	padding: 0.25em; 
}
 
/*div.dokuwiki div.page */
div.cloud div#left { 
	margin-bottom: 1em; 
	float:left;
	width:400px;
	clear:left;
}
 
/*div.dokuwiki div.page */
div.cloud div#right { 
	margin-bottom: 1em; 
	float:left;
	clear:none;
}
 
/*div.dokuwiki div.page div.cloud  */
fieldset.cloud { 
	margin-bottom: 1em; 
	text-align:left;
	clear:none;
}
 
/*div.dokuwiki div.page div.cloud */ 
textarea#stopwords { 
	margin-bottom: 1em; 
	float:left;
	width:250px;
}
 
/*div.dokuwiki div.page div.cloud */ a.cloud1   { font-size: 10px; color: #D3E0F5; }
/*div.dokuwiki div.page div.cloud */ a.cloud1_a { font-size: 10px; color: #D3E0F5; }
/*div.dokuwiki div.page div.cloud */ a.cloud2   { font-size: 12px; color: #AEC4E5; }
/*div.dokuwiki div.page div.cloud */ a.cloud2_a { font-size: 12px; color: #AEC4E5; }
/*div.dokuwiki div.page div.cloud */ a.cloud3   { font-size: 14px; color: #88A9DB; }
/*div.dokuwiki div.page div.cloud */ a.cloud3_a { font-size: 14px; color: #88A9DB; }
/*div.dokuwiki div.page div.cloud */ a.cloud4   { font-size: 16px; color: #4A7AC2; }
/*div.dokuwiki div.page div.cloud */ a.cloud4_a { font-size: 16px; color: #4A7AC2; }
/*div.dokuwiki div.page div.cloud */ a.cloud5   { font-size: 18px; color: #003F9E; }
/*div.dokuwiki div.page div.cloud */ a.cloud5_a { font-size: 18px; color: #006666; }
 
/*div.dokuwiki div.page div#cloud */ a.cloud1_tag1 { font-size: 10px; color: #CEF0D0; }
/*div.dokuwiki div.page div#cloud */ a.cloud2_tag1 { font-size: 12px; color: #AEE5B1; }
/*div.dokuwiki div.page div#cloud */ a.cloud3_tag1 { font-size: 14px; color: #88DB8C; }
/*div.dokuwiki div.page div#cloud */ a.cloud4_tag1 { font-size: 16px; color: #4AC250; }
/*div.dokuwiki div.page div#cloud */ a.cloud5_tag1 { font-size: 18px; color: #009E08; }
/*div.dokuwiki div.page div#cloud */ a.cloud1_tag2 { font-size: 10px; color: #F0CED7; }
/*div.dokuwiki div.page div#cloud */ a.cloud2_tag2 { font-size: 12px; color: #E5AEBC; }
/*div.dokuwiki div.page div#cloud */ a.cloud3_tag2 { font-size: 14px; color: #DB889D; }
/*div.dokuwiki div.page div#cloud */ a.cloud4_tag2 { font-size: 16px; color: #C24A68; }
/*div.dokuwiki div.page div#cloud */ a.cloud5_tag2 { font-size: 18px; color: #9E0028; }
 
/*div.dokuwiki div.page */ div#cloud span:hover { text-decoration:underline; cursor:pointer; color:#00CC00; }

My site (http://www.puzzlers.org/) uses a slightly more complex presentation so the cloud is presented well. I use:

<html><div class='cloud'>
      <fieldset class='wordcloud' class='cloud'>
      <legend id='wordcloud'>Our Most Common Terms</legend>
</html>~~CLOUD:200~~<html>
      </fieldset>
</div> <!-- class='cloud' --></html>

This makes my cloud show up in a box with a heading “Our Most Common Terms.” It also provides a <div> wrapper making positioning easier. The <html> ... </html> tags assume your site permits direct entry of HTML into pages.

Areas for Improvement
  • In the CSS, reduce the bounds on the clickable area of a word since I often seem to be hitting the word below the one I want.
  • The JavaScript seems to insist on double spacing new words.
  • This is pretty much untested regarding the tagcloud since I don't have the tag plugin.

Kite [at] Puzzlers [dot] org on June 17, 2008.

Admin Page v1.1 Comments

The Admin page plugin works very well with my browser (IE7) after Kite helped with style.css and admin.php fixes. This is the best word cloud I have seen and anyone interested in using it should at least try this and see for themselves. It is simple to use and makes use of 'stopwords' a great deal easier. Thanks for the fixes Kite. Chris 11/07/2008

Is this really /inc/plugins and not /lib/plugins/… ? Daniel, 2008.08.13

tag cloud erratic behavior

“I get a strange behavior : tagcloud lists tags from pages that where canceled, and forgets many other tags” : try to re-build tag index in the Admin pannel.8-)

Tag Exclude

I'm using this plugin with the tags plugin and I'm loving it. However, there are a few tags I use for admin-type purposes and would rather not include in the cloud. I made some edits to the _getTagCloud function, but I can't seem to find a comparison between the tag name ($key) and the contents of the $stoptags array that ever returns positive. Here is the mostly cut-and-pasted-from-other-sections code I was working with:

    /**
     * Returns the sorted tag cloud array
     */
    function _getTagCloud($num, &$min, &$max, &$tag) {
 
	    // load stoptags
        $swfile   = DOKU_INC.'inc/lang/'.$conf['lang'].'/stoptags.txt';
        if (@file_exists($swfile)) $stoptags = file($swfile);
        else $stoptags = array();
 
        // load extra local stoptags
        $swfile = DOKU_CONF.'stoptags.txt';
        if (@file_exists($swfile)) $stoptags = array_merge($stoptags, file($swfile));
 
        $cloud = array();
        foreach ($tag->topic_idx as $key => $value) {
            if (!is_array($value) || empty($value) || (!trim($value[0])) || is_int(array_search("$key", $stoptags))) continue;
	        $cloud[$key] = count($value);
        }
 
        return $this->_sortCloud($cloud, $num, $min, $max);
    }

I suspect this will be easy for someone more familiar with PHP. Can anyone figure this out? Thanks!

Tag Cloud behaves erratically

Immediately after a tag index rebuild, everything is going fine using the newest tag and cloud plugins. After a few minutes, or few visits I am not sure, everything is screwed up since font sizes do not correspond to number of backlinks. Sometimes all tags have the same size. Incidentally if I click in one tag, it returns the backlinks and also it backs to its right size.

You can check it at my blog at http://profs.if.uff.br/tjpp/blog.

Thadeu Penna 2008/10/14 22:17

Hmmm, there's something wrong indeed. Could you please open a bug at the bug tracker linked on this page (I just added it ;-)). Thanks in advance. — Michael Klier 2008/10/15 13:58
I upgraded the DokuWiki and tag plugins and the tag cloud shows the right thing so far (four days). I will close the bug report. Thanks a lot! — Thadeu Penna 2009-3-16 19:18

Tag shows 1st headlines, not page names

Hello there, I have correctly set up a cloud of tags on a sidebar using Arctic plugin. My problem is that the result of clicking on a tag is a list of 1st heading of the page. Is there a way to make the results be displayed as pagenames?

Uderman 2009/03/11 09:57

Displaying of list is on the tag plugin

Vovanium

National characters bug with romanization

When I enabled romanization and use national characters in tags, links to page list are incorrect, because tag names aren't romanized. The solution is make line 87 of syntax.php look like

                      $link = wl($id, array('do'=>'showtag', 'tag'=>$word)); // patch

instead of

                      $link = wl($id, array('do'=>'showtag', 'tag'=>noNS($id)));

Vovanium

Words smaller than 4 letters

Is there any way of removing words with 3, 2 and 1 letters from a cloud? (except entering every appeared word to the stopwords.txt)

Oh… I think I have figured this out… Because I have words in Russian and letters in them are encoded as digits with '%', the plugin counts more letters than there are. And minimum word length in syntax.php doesn't work well in this case…

Seykela 2009/03/28

Open: /inc/indexer.php line 48:

/**
 * Measure the length of a string.
 * Differs from strlen in handling of Asian characters.
 *
 * @author Tom N Harris <tnharris@whoopdedo.org>
 */
function wordlen($w)
{
    $l = strlen($w);
    // If left alone, all chinese "words" will get put into w3.idx
    // So the "length" of a "word" is faked
    if(preg_match('/'.IDX_ASIAN2.'/u',$w))
        $l += ord($w) - 0xE1;  // Lead bytes from 0xE2-0xEF
    return $l;
}

Replace with:

/**
 * Measure the length of a string.
 *
 * @author Konstantin <kot@ereality.org>
 */
function wordlen($w)
{
	return mb_strlen($w);
}

Then rebuild search index! Good luck :-)

Konstantin 2009/04/26

plugin/cloud/discussion_old.txt · Last modified: 2010-12-31 18:54 by lupo49