1 #+OPTIONS: H:3 num:nil toc:t \n:nil ::t |:t ^:t -:t f:t *:t tex:t d:(HIDE) tags:not-in-toc
2 #+STARTUP: align fold nodlcheck hidestars oddeven lognotestate
3 #+SEQ_TODO: TODO(t) INPROGRESS(i) WAITING(w@) | DONE(d) CANCELED(c@)
4 #+TAGS: Write(w) Update(u) Fix(f) Check(c)
5 #+TITLE: Publishing Treemenus for Org-files
6 #+AUTHOR: Sebastian Rose
7 #+EMAIL: sebastian_rose gmx de
9 #+CATEGORY: worg-tutorial
10 #+SETUPFILE: ../macros.setupfile
13 [[file:../index.org][{Back to Worg's index}]]
17 You should be comfortable with publishing Org-mode fiels to HTML already when
18 you read this. Make sure, to create the tree-style sitemap-file on export.
20 This Tutorial describes a simple technique to include published content into
21 other web applications. I use an external JavaScript treemenu library publish
22 by Marco Pratesi. This treemenu is fast and runs in all Browsers I'm aware
23 of. The techniqe could as well be adopted to other menu libs.
25 You might as well use the Menu as kind of sitemap or top menu.
27 - The homepage of Phplaymenu is here: http://sourceforge.net/projects/phplayersmenu/
28 - A demo can be found on http://phplayersmenu.sourceforge.net/demo.php
30 Here is a screenshot of a treemenu:
32 #+CAPTION: Example phplayersmenu treemenu
33 #+ATTR_HTML: style="margin-left:auto;margin-right:auto;text-align:center;"
34 [[file:../images/sr/phplayermenu-example-tree.png]]
36 {{{BeginInfoBox}}} *Note:* Prior to Org-mode commit
37 [[https://code.orgmode.org/bzg/org-mode/commit/4892c8899e5b99d041836749fb2d1458971be55d][4892c8899e5b99d041836749fb2d1458971be55d]] (version 6.34trans), =sitemap-file=
38 =auto-sitemap= a.s.o. where called =index-file=, =auto-index= and similar. I you
39 have to work with a version released before 25th of February 2010, just
40 replace =sitemap= with =index= throughout this file.
46 The menus are read from a string of a special structure. While it is beyond
47 this tutorial to explain the usage of the menus in details, the structure of
48 this string is important.
50 Each line of the string consists of these elements:
52 : [dots]|[text]|[link]|[title]|[icon]|[target]|[expanded]
54 Everything in brackets is optional. So are any trailing bars, if empty.
56 The tree structure is represented by prepended dots.
60 : .|Top level directory without link
61 : ..|Article 1|articles/article1.html|||main
62 : ..|Article 2|articles/article2.html|||main
64 : ..|C++|snippets/c++.html|||main
65 : ..|Perl|snippets/Perl.html|||main
67 will result in either in a tree menu like this here (=[F]= is an optional
70 : - [F] Top level directory without link
80 ...or a menubar like this:
82 : .__________________________________.__________.
83 : | Top level directory without link | Snippets |
84 : `----------------------------------| |
90 * Creating the menu structure when publishing
92 To create the menu structure, I use a modified version of the elisp function
93 =org-publish-org-sitemap=, defined in =Org-mode/lisp/org-publish.el=, that generates
94 the sitemap for HTML export. The function is called
95 =sr-org-notes-sitemap-complete= and defined in one of my emacs setup files.
97 Fortunately, Org-mode makes it possible to call a function after the
98 publishing process has fineshed. To make use of =sr-org-notes-sitemap-complete=,
99 add this to your publishing project's definition:
101 #+begin_src emacs-lisp
102 (require 'org-publish)
103 (setq org-publish-project-alist
105 :base-directory "~/org/notes/"
110 :auto-sitemap t ; generate sitemap.org automagically
111 :sitemap-filename "sitemap.org" ; this is the default
112 :sitemap-style "tree"
115 :completion-function sr-org-notes-sitemap-complete
116 :menu/structure-file "~/path/to/menu-structure-file.txt"
117 :menu/link-target "mitte" ;; optional
124 Once you re-publish your project, the menu-structure file will be created.
126 * =my-org-notes-sitemap-complete=
128 #+begin_src emacs-lisp
129 (defun sr-org-notes-sitemap-complete ()
130 "Take the sitemap-file and turn it into the menu-structure
131 file for Marco Pratesi's phplayersmenu."
132 (let* ((base-dir (file-name-as-directory (plist-get project-plist :base-directory)))
133 (orig (expand-file-name (concat base-dir (plist-get project-plist :sitemap-filename))))
134 (strip-suffix (or (plist-get project-plist :base-extension) "org"))
135 (add-suffix (or (plist-get project-plist :html-extension) "html"))
136 (link-target (or (plist-get project-plist :menu/link-target) "_blank"))
137 (menu-file (or (plist-get project-plist :menu/structure-file) nil))
139 (visiting (find-buffer-visiting orig))
140 (visiting-output (find-buffer-visiting menu-file))
142 (input-buffer (find-file orig))
143 (output-buffer (find-file menu-file))
150 (throw 'sr-org-note-kb-completion-error
151 "No menu structure file provided. Giving up."))
153 (with-current-buffer output-buffer
156 (with-current-buffer input-buffer
158 (goto-char (point-min))
159 (while (re-search-forward org-bracket-link-analytic-regexp (point-max) t)
160 (let ((link (match-string-no-properties 3))
161 (text (match-string-no-properties 5))
165 (with-current-buffer output-buffer
166 (if (string-match (concat "\\(" strip-suffix "\\)$") link)
167 (setq link (replace-match add-suffix t t link)))
168 (while (setq pos (string-match "/" link pos))
169 (setq ndots (+ ndots 1))
170 (setq pos (+ pos 1)))
173 (string-match "\\(/[^/]*\\)$" link)
174 (setq sub (replace-match "" t t link))
176 (unless (string= sub old-sub)
178 (subs (split-string sub "/"))
179 (old-subs (split-string old-sub "/")))
180 (while (string= (car old-subs) (car subs))
188 (make-string ds ?.) "|" d "\n")))
189 (setq old-sub sub))))
193 (make-string ndots ?.) "|" text "|" link "|||" link-target "\n"))
194 (setq old-ndots ndots)
197 (or visiting (kill-buffer input-buffer))
199 (with-current-buffer output-buffer
201 (or visiting-output (kill-buffer output-buffer))
206 * Include the menu in existing pages
208 To actually use the result, download the Phplayersmenu library and unpack
209 it. Move the following subfolders to your webroot:
211 * =phplayersmenu-3.2.0/lib/=
212 * =phplayersmenu-3.2.0/libjs/=
213 * =phplayersmenu-3.2.0/menuimages/=
215 Also choose one of the stylesheets in =phplayersmenu-3.2.0/=. In the example
216 below, the =layerstreemenu.css= is used.
218 Adjust the file(s) you want to include the menu in. Here is an example:
220 #+begin_src html -n -r
223 <script type="text/javascript">
224 <?php include ("libjs/layersmenu-browser_detection.js"); ?>
226 <link rel="stylesheet" href="layerstreemenu.css" type="text/css"></link> (ref:tree1)
227 <script type="text/javascript" src="libjs/layerstreemenu-cookies.js"></script>
235 include ("lib/PHPLIB.php"); // taken from PHPLib
236 include ("lib/layersmenu-common.inc.php");
237 include ("lib/treemenu.inc.php"); (ref:tree2)
238 if ( @ is_file ("../intranet/navigations/org.txt") )
240 $mid = new TreeMenu(); (ref:tree3)
241 $mid->setMenuStructureFile("navigations/org.txt");
242 $mid->setPrependedUrl("../org-notes/"); (ref:url1)
243 $mid->parseStructureForMenu("treemenu1");
244 print $mid->newTreeMenu("treemenu1"); (ref:tree4)
252 What makes your menu a tree-menu, are
254 * the stylesheet ([[(tree1)][line (tree1)]]),
255 * theinclusion of treemenu.inc.php ([[(tree2)][in line (tree2)]]),
256 * the constructor used ([[(tree3)][line (tree3)]]),
257 * and the =newTreeMenu()= method ([[(tree4)][called in line (tree4)]]).
259 The (optional) [[(url1)][URL provided in line (url1)]] is prepended to all the URLs found
260 in the menu-structure file.
262 See the Phplayersmenu docs on how to create horizontal and vertical menus from
263 the same structure file.