Opened 13 years ago

Closed 12 years ago

#67 closed defect (fixed)

Patch: Linker-Plugin - labels for files

Reported by: Niko <ns@…> Owned by: gogo
Priority: normal Milestone:
Component: Xinha Core Version:
Severity: normal Keywords:
Cc:

Description

Patch: labels for files

If you have a dynamic website links may look like this: http://www.example.com/news.php?id=34.

When using the Linker-Plugin you can write our own backend file to get all news-links out of a database (or you use #66), but you can't give these links a title, they stay as news.php?id=34 in the tree.

With this patch it is possible to give everay link a specific caption - so the links to the news can have a nice caption (fetched from the database too of course).

Usage-Example, scan.php should return an object like this:

//old syntax (still works)
['/info.php', [ [ '/news', [ '/news.php?id=33', '/news.php?id=34' ] ] ] ];

//new syntax
lDialog.files = {'/info.php': 'Info', 0:[ 'News',  { '/news.php?id=33': 'News Number 33', '/news.php?id=34': 'News with the ID 34' } ] };

//new syntax, where you can select the folder "News" too
lDialog.files = {'/info.php': 'Info', 'newslist.php':[ 'News',  { '/news.php?id=33': 'News Number 33', '/news.php?id=34': 'News with the ID 34' } ] };

(I don't understand why i need this 'lDialog.files = ', it won't work without it)

Please review this patch carefully... i'm not a good JavaScript?-coder :D

--- linker.js   (Revision 38)
+++ linker.js   (Arbeitskopie)
@@ -362,20 +368,42 @@

 Linker.Dialog.prototype.makeNodes = function(files, parent)
 {
-  for(var i = 0; i < files.length; i++)
+  //convert array to a object (key and val are the same then)
+  if(files.length)
   {
-    if(typeof files[i] == 'string')
+    var files2 = new Object();
+    for(var i = 0; i < files.length; i++) {
+      if(typeof files[i] == 'string') {
+        files2[files[i]] = files[i];
+      } else {
+        files2[i] = files[i];
+      }
+    }
+  }
+  else
+  {
+    var files2 = files;
+  }
+
+  for(var i in files2)
+  {
+    if(typeof files2[i] == 'string')
     {
       this.dTree.add(Linker.nxtid++, parent,
-                     files[i].replace(/^.*\//, ''),
-                     'javascript:document.getElementsByName(\'' + this.dialog.id.href + '\')[0].value=unescape(\'' + escape(files[i]) + '\');document.getElementsByName(\'' + this.dialog.id.type + '\')[0].click();document.getElementsByName(\'' + this.dialog.id.href + '\')[0].focus();void(0);',
-                     files[i]);
+                     files2[i].replace(/^.*\//, ''),
+                     'javascript:document.getElementsByName(\'' + this.dialog.id.href + '\')[0].value=unescape(\'' + escape(i) + '\');document.getElementsByName(\'' + this.dialog.id.type + '\')[0].click();document.getElementsByName(\'' + this.dialog.id.href + '\')[0].focus();void(0);',
+                     files2[i]);
     }
     else
     {
+      if(i=="0" || i+0 > 0) {
+        var target = null;
+      } else {
+        var target = 'javascript:document.getElementsByName(\'' + this.dialog.id.href + '\')[0].value=unescape(\'' + escape(i) + '\');document.getElementsByName(\'' + this.dialog.id.type + '\')[0].click();document.getElementsByName(\'' + this.dialog.id.href + '\')[0].focus();void(0);';
+      }
       var id = this.Dialog_nxtid++;
-      this.dTree.add(id, parent, files[i][0].replace(/^.*\//, ''), null, files[i][0]);
-      this.makeNodes(files[i][1], id);
+      this.dTree.add(id, parent, files2[i][0].replace(/^.*\//, ''), target, files2[i][0]);
+      this.makeNodes(files2[i][1], id);
     }
   }
 }

Attachments (2)

.2 (0 bytes) - added by anonymous 12 years ago.
.3 (0 bytes) - added by anonymous 12 years ago.

Download all attachments as: .zip

Change History (8)

comment:1 Changed 13 years ago by gogo

I'm not sure that you have the best method of doing it there.

What I'd like to do is make the structure something like

  // Files is a structure of nodes and node-lists
  // <<node-list>> = [ <<node>, <<node>>, ...]  
  // <<node>> = one of the following four types
  // 1. "a.html" -- URL without children or title
  // 2. ["a.html", <<node-list>>] -- URL without title but with children
  // 3. {url:"a.html",title:"A URL"} -- URL with title
  // 4. {url:"a.html",title:"A File",children:<<node-list>>} -- URL with title, and children
  
  // Complex Example
  //    
  //    [
  //      "e.html",                        
  //      ['f.html', ['g.html','h.html']], 
  //      {url:'i.html',title:'I Html'},   
  //      {url:'j.html',title:'J Html, children:[{url:'k.html',name:"K Html"},'l.html',['m.html',['n.html']]]} 
  //    ]  
  //    
  //   produces something like
  //    e.html
  //    f.html
  //      g.html
  //      h.html
  //    I Html
  //    J Html
  //      K Html
  //      l.html
  //      m.html
  //        n.html

Type 3 and 4 nodes would be the preference, I'd go so far as to deprecate type 1 and 2. The main advantage of this method particularly with type 3 & 4 nodes is readability for the programmer. Also over your method, object properties can't really be thought of as ordered (when you do for(var i in foo) how do you know if foo.bar will come before foo.narf?)

This will work for the default scan.php (it uses type 1 and type 2 nodes), however your own code would need to be modified as it's not quite the same.

What do you think?

comment:2 Changed 13 years ago by Niko <ns@…>

great, much more clearer than my idea :D
will you implement this?

(shouldn't be a problem for me to change my code....)

comment:3 Changed 13 years ago by Niko <ns@…>

wrote a little patch for your method:

--- plugins/Linker/linker.js    (Revision 48)
+++ plugins/Linker/linker.js    (Arbeitskopie)
@@ -383,12 +383,29 @@
                      'javascript:document.getElementsByName(\'' + this.dialog.id.href + '\')[0].value=decodeURIComponent(\'' + encodeURIComponent(files[i]) + '\');document.getElementsByName(\'' + this.dialog.id.type + '\')[0].click();document.getElementsByName(\'' + this.dialog.id.href +'\')[0].focus();void(0);',
                      files[i]);
     }
-    else
+    else if(files[i].length)
     {
       var id = this.Dialog_nxtid++;
       this.dTree.add(id, parent, files[i][0].replace(/^.*\//, ''), null, files[i][0]);
       this.makeNodes(files[i][1], id);
     }
+    else if(typeof files[i] == 'object')
+    {
+      if(files[i].children) {
+        var id = this.Dialog_nxtid++;
+      } else {
+        var id = Linker.nxtid++;
+      }
+      var title = files[i].title ? files[i].title : files[i].url;
+      this.dTree.add(id, parent,
+                     title.replace(/^.*\//, ''),
+                     'javascript:document.getElementsByName(\'' + this.dialog.id.href + '\')[0].value=decodeURIComponent(\'' + encodeURIComponent(files[i].url) + '\');document.getElementsByName(\'' + this.dialog.id.type + '\')[0].click();document.getElementsByName(\'' + this.dialog.id.href + '\')[0].focus();void(0);',
+                     title);
+      if(files[i].children) {
+        this.makeNodes(files[i].children, id);
+      }
+    }
   }
 }

...look at it carefully

  • i didn't know how to check if files[i] is an array (typeof returns object) so i used if(files[i].length)
  • the part with the id (this.Dialog_nxtid and Linker.nxtid) is too high for me... don't now if it is neccessary like i did it.... (probalby we could always use this.Dialog_nxtid)
  • what happens if files[i].url is not set? (currently a JS error will be produced...)

comment:4 Changed 13 years ago by riftdesign

Great patch Niko! There are two things which I have found that might need to be revisited:

  1. Titles with single quotes need to be escaped, but it doesn't seem to work using \'
  2. If scan.php generates malformed data, an error should be shown

comment:5 Changed 12 years ago by anonymous

new version of my patch, changes:

  • now works with no url (non-clickable-direcotries)
  • patch for scan.php is included that it will use the new vormat
Index: linker.js
===================================================================
--- linker.js   (Revision 54)
+++ linker.js   (Arbeitskopie)
@@ -383,12 +390,31 @@
                      'javascript:document.getElementsByName(\'' + this.dialog.id.href + '\')[0].value=decodeURIComponent(\'' + encodeURIComponent(files[i]) + '\');document.getElementsByName(\'' + this.dialog.id.type + '\')[0].click();document.getElementsByName(\'' + this.dialog.id.href + '\')[0].focus();void(0);',
                      files[i]);
     }
-    else
+    else if(files[i].length)
     {
       var id = this.Dialog_nxtid++;
       this.dTree.add(id, parent, files[i][0].replace(/^.*\//, ''), null, files[i][0]);
       this.makeNodes(files[i][1], id);
     }
+    else if(typeof files[i] == 'object')
+    {
+      if(files[i].children) {
+        var id = this.Dialog_nxtid++;
+      } else {
+        var id = Linker.nxtid++;
+      }
+
+      if(files[i].title) var title = files[i].title;
+      else if(files[i].url) var title = files[i].url.replace(/^.*\//, '');
+      else var title = "no title defined";
+      if(files[i].url) var link = 'javascript:document.getElementsByName(\'' + this.dialog.id.href + '\')[0].value=decodeURIComponent(\'' + encodeURIComponent(files[i].url) + '\');document.getElementsByName(\'' + this.dialog.id.type + '\')[0].click();document.getElementsByName(\'' + this.dialog.id.href + '\')[0].focus();void(0);';
+      else var link = '';
+
+      this.dTree.add(id, parent, title, link, title);
+      if(files[i].children) {
+        this.makeNodes(files[i].children, id);
+      }
+    }
   }
 }

Index: scan.php
===================================================================
--- scan.php    (Revision 54)
+++ scan.php    (Arbeitskopie)
@@ -61,13 +78,14 @@
           {
             if($subdir = scan($path, $url))
             {
-              $files[] = array($url, $subdir);
+              $files[] = array('url'=>$url, 'children'=>$subdir);
             }
           }
           elseif(is_file($path))
           {
             if(($include && !preg_match($include, $url)) || ($exclude && preg_match($exclude, $url))) continue;
-            $files[] = $url;
+            $files[] = array('url'=>$url);
           }

         }
@@ -103,12 +121,30 @@

       if(is_array($var))
       {
+        $useObject = false;
+        foreach(array_keys($var) as $k) {
+            if(!is_numeric($k)) $useObject = true;
+        }
         $js = array();
         foreach($var as $k => $v)
         {
-          $js[] = to_js($v, $tabs + 1);
+          $i = "";
+          if($useObject) {
+            if(preg_match('#[a-zA-Z]+[a-zA-Z0-9]*#', $k)) {
+              $i .= "$k: ";
+            } else {
+              $i .= "'$k': ";
+            }
+          }
+          $i .= to_js($v, $tabs + 1);
+          $js[] = $i;
         }
-        return "[\n" . tabify(implode(",\n", $js), $tabs) . "\n]";
+        if($useObject) {
+            $ret = "{\n" . tabify(implode(",\n", $js), $tabs) . "\n}";
+        } else {
+            $ret = "[\n" . tabify(implode(",\n", $js), $tabs) . "\n]";
+        }
+        return $ret;
       }

       return 'null';
 ?>

comment:6 Changed 12 years ago by niko

  • Resolution set to fixed
  • Status changed from new to closed

commited this patch as changeset:57, additional info about syntax in wiki:Linker

Changed 12 years ago by anonymous

Changed 12 years ago by anonymous

Note: See TracTickets for help on using tickets.