Author: pke Date: Wed Dec 19 23:46:08 2007 New Revision: 7029 Log: Finished edit on Tree article
Modified: docs/articles/2007-12-20-tree-yui.txt Modified: docs/articles/2007-12-20-tree-yui.txt ============================================================================== --- docs/articles/2007-12-20-tree-yui.txt [iso-8859-1] (original) +++ docs/articles/2007-12-20-tree-yui.txt [iso-8859-1] Wed Dec 19 23:46:08 2007 @@ -1,6 +1,6 @@ -======================================================= -The Tree component and Yahoo User Interface integration -======================================================= +======================================================== +The Tree component and Yahoo! User Interface integration +======================================================== :Author: Derick Rethans :Date: 2007-12-20 10:39 @@ -11,8 +11,8 @@ enables you to create, manipulate and query tree structures in many ways. In addition to its basic functionality, the component also enables you to render the tree structure in different ways, with different visualizers. In this article, -we will create output from an XML tree definition in order to create a nice -menu using the Yahoo User Interface library. +we will render output from an XML tree definition in order to create a nice +menu using the Yahoo! User Interface library. .. _Tree: /docs/tutorials/Tree @@ -22,7 +22,7 @@ an image representing your tree structure. Because a tree is often a good representation of the structure of a website, it can be useful to use this class to generate a menu for your website. One of the nicer widgets to do so is -Yahoo User Interface's (`YUI's`_) `menu widget`_. The Tree component also +Yahoo! User Interface's (`YUI's`_) `menu widget`_. The Tree component also contains a YUI menu visualizer to help you easily create website menus. The menu you see on http://ezcomponents.org/ is based on the Tree component, combined with the YUI menu widget. @@ -39,13 +39,13 @@ YUI Introduction ================ -The *Yahoo User Interface library* contains many widgets and many +The *Yahoo! User Interface library* contains many widgets and many different types of menus. The Tree component's YUI visualizer (ezcTreeVisitorYUI_) currently produces XHTML for the "Website Top Nav With Submenus Built From Markup" menu only. An example__ of this type of menu can be found on the YUI `menu widget`_ documentation site. The YUI widgets depend on a specific set of JavaScript files, which you can either copy to your local server or -request in your script from the Yahoo website. YUI also comes with a predefined +request in your script from the Yahoo! website. YUI also comes with a predefined stylesheet that **must** be used, although it allows for re-styling with CSS. There is a guide on "skinning__" available on the YUI website, although it is a bit limited. There are plenty of other things that can be @@ -107,8 +107,8 @@ #. The "node" element can have an optional "data" element from the namespace "etd" #. The "node" element can have zero to many "node" elements as children -We will leave out the data parts for now and look only at the structure. Part -of the structure of XML file looks like this:: +We will leave out the data parts for now and look only at the structure. Let's +start with an XML file for the tree that looks like this:: <?xml version="1.0" encoding="utf-8"?> <!DOCTYPE tree PUBLIC "" ""> @@ -166,18 +166,20 @@ <etd:data>Search page</etd:data> </node> -However, this is not sufficient in our case, as we also need to know what type -of object belongs to the node. For example, the object could be a PHP script or a -rendered reStructuredText__ file. For the eZ Components website, we solve this -by using a database store (ezcTreeDbDataStore__), as this can store the data in -extra columns of the same database table. However, in this tutorial we will -extend the ezcTreeXmlInternalDataStore class to allow for multiple "fields" of -data. - +However, this is not sufficient for the eZ Components site, as we also need to +know what type of object belongs to the node. For example, the object could be +a PHP script or a rendered reStructuredText__ file. For the eZ Components +website, we solve this by using a database store (ezcTreeDbDataStore__), as +this can store the data in extra columns of the same database table. Although +we will not use the type information when generating the menu in our example, +it is a good demonstration of how easily the data stores can be extended. +Therefore, in this tutorial we will extend the ezcTreeXmlInternalDataStore +class to allow for multiple "fields" of data. + +__ http://en.wikipedia.org/wiki/RELAX_NG#Compact_syntax __ /s/ezcTreeXmlInternalDataStore __ http://docutils.sourceforge.net/rst.html __ /s/ezcTreeDbDataStore -__ http://en.wikipedia.org/wiki/RELAX_NG#Compact_syntax Extending the data store ~~~~~~~~~~~~~~~~~~~~~~~~ @@ -199,10 +201,10 @@ As you can see from the example above, we created the ezcaTreeXmlDataStore class. Note that the prefix for the class name is "ezca", not "ezc". In order to prevent naming clashes, we strongly recommend that all classes that are not -part of the eZ Components code avoid use the "ezc" prefix. In this case, we use +part of the eZ Components code avoid using the "ezc" prefix. In this case, we use "ezca", which stands for "eZ Components Article". When we run the example using the new class, the same exception is thrown when fetching the node data. This -is because because we haven't reimplemented the methods of the data store yet. +is because we haven't reimplemented the methods of the data store yet. The ezcTreeDataStore__ interface describes five methods that should be implemented for each data store. Because our data is embedded in XML data @@ -220,9 +222,9 @@ __ /s/ezcTreeDataStore __ /s/ezcTreeNodeList -Instead of trying to parse complex XML structures, we will just store both +Instead of trying to parse complex XML structures, we will store both pieces of information (type of page and name) in -the same text element, separated by a semicolon (:). Below is an example of +the same text element, separated by a colon (:). Below is an example of two nodes with the data presented as described:: <node id="resources"> @@ -231,6 +233,10 @@ <node id="search"> <etd:data>php:Search</etd:data> </node> + +The first field of the data will contain the object type - for example, "rst" +for a rendered reStructuredText file, and "php" for a PHP script. The +second field contains the nice name to show for this node. The implementation of the fetchDataForNode() method is copied from the original file. The second-to-last line used to read:: @@ -242,8 +248,10 @@ $node->data = split( ':', $dataElem->firstChild->data ); -Here is the script again, with the reimplemented method in place. The -last line has been changed to dump an array:: +Here is the script again, with the reimplemented method in place. The last line +has been changed to dump an array, as the previous usage +of "echo" was suitable when we had only one piece of information in a text +element:: <?php require 'ezc/Base/ezc_bootstrap.php'; @@ -297,8 +305,39 @@ string(13) "Documentation" } -The full example can be found in the downloadable archive (see left menu) with +The full example can be found in the downloadable archive (see the left menu) with examples with the filename ``extend1.php``. + +The final XML file is pasted below:: + + <?xml version="1.0" encoding="utf-8"?> + <!DOCTYPE tree PUBLIC "" ""> + <tree xmlns="http://components.ez.no/Tree" xmlns:etd="http://components.ez.no/Tree/data"> + <node id="root"> + <etd:data>php:Homepage</etd:data> + <node id="overview"> + <etd:data>rst:Overview</etd:data> + <node id="requirements"><etd:data>rst:PHP Requirements</etd:data></node> + <node id="license"><etd:data>rst:License</etd:data></node> + <node id="roadmap"><etd:data>rst:Roadmap</etd:data></node> + </node> + <node id="docs"> + <etd:data>rst:Documentation</etd:data> + <node id="install"><etd:data>rst:Installation Guide</etd:data></node> + <node id="tutorials"><etd:data>php:Tutorials</etd:data></node> + <node id="api"><etd:data>php:API Reference</etd:data></node> + </node> + <node id="resources"> + <etd:data>php:Resources</etd:data> + <node id="news"><etd:data>php:News Archive</etd:data></node> + <node id="articles"><etd:data>php:Articles and Publications</etd:data></node> + <node id="presentations"><etd:data>php:Presentation Slides</etd:data></node> + </node> + <node id="search"> + <etd:data>php:Search</etd:data> + </node> + </node> + </tree> Example plain text rendering ---------------------------- @@ -337,8 +376,9 @@ This example's source code can be found in the archive with examples with the filename ``visitor1.php``. -Unfortunately, it does not seem to use the pretty names for all the nodes. In -order to solve that, we need to subclass the ezcTreeVisitorPlainText__ class. +Unfortunately, it does not use the nice names that we created earlier for the +nodes. Instead, it outputs the respective node IDs. In order to solve this, we +need to subclass the ezcTreeVisitorPlainText__ class. We override the visit() method of this class as follows:: class ezcaTreeVisitorPlainText extends ezcTreeVisitorPlainText @@ -362,10 +402,11 @@ } } -The original class had instead of the ``->data[1]`` bits ``->id``. -When we modify the original script to use to new inherited visitor, -ezcaTreeVisitorPlainText, the output turns into the more pleasant display -below:: +The original class had ``->id`` instead of the parts that now have +``->data[1]``. The new class thus grabs the nice names instead of the node IDs. +When we modify the original script to use the new inherited +visitor class, ezcaTreeVisitorPlainText, the output turns into the more +pleasant display below:: Homepage ââOverview @@ -400,7 +441,7 @@ -------------------- First of all, you need to include the correct JavaScript. We refer to them -from the Yahoo servers, but of course you can also download and refer to them +from the Yahoo! servers, but of course you can also download and refer to them locally. The lines below should be placed in the "head" section of your HTML file:: <!-- Dependencies --> @@ -409,19 +450,19 @@ <!-- Source File --> <script type="text/javascript" src="http://yui.yahooapis.com/2.3.1/build/menu/menu-min.js"></script> -In the same "head" section you should also place the default CSS for the YUI menu:: +In the same "head" section you should also refer to the default CSS for the YUI menu:: <link rel="stylesheet" type="text/css" href="http://yui.yahooapis.com/2.3.1/build/menu/assets/skins/sam/menu.css"/> -The two snippets above make YUI accessible, but they will not produce anything +The two snippets above make the YUI accessible, but they will not produce anything until you add some JavaScript code to attach the YUI menu classes and JavaScript to the menu itself. Rendering the menu ------------------ -To produce the XHTML in a format that YUI accepts, first we use the -ezcTreeVisiterYUI__ class instead of the ezcTreeVisitorPlainText_ class that we +To produce the XHTML in a format that the YUI accepts, first we use the +ezcTreeVisitorYUI__ class instead of the ezcTreeVisitorPlainText_ class that we used before:: // display the tree @@ -439,7 +480,7 @@ By default, data stores return only a string, but we have modified the data store to return an array. Because of this, the script will now output lots of -warnings, like the following:: +warnings like the following:: Warning: htmlspecialchars() expects parameter 1 to be string, array given in /home/derick/dev/ezcomponents/trunk/Tree/src/visitors/yui.php on line 101 @@ -481,7 +522,7 @@ Tying everything together, we end up with the following code to render the YUI menu. This example can be found in the downloadable archive -(see left menu) with examples with the filename ``full1.php``:: +(see the left menu) with examples with the filename ``full1.php``:: <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"> @@ -549,18 +590,18 @@ Styling ------- -Styling the menu is done with CSS. The YUI widget's default CSS all use the +Styling the menu is done with CSS. The YUI widget's default CSS elements all use the *yui-skin-sam* namespace. Overriding specific classes of YUI widgets is therefore quite easy. However, there are a lot of different elements that -need restyling - some advanced CSS skills might be required to make the menu -look exactly as you would like. FireBug__ is an excellent browser plugin that +can be re-styled - some advanced CSS skills might be required to make the menu +look exactly as you would like. Firebug__ is an excellent browser plugin that helps you to inspect and edit the CSS and HTML on your site. __ http://www.getfirebug.com/ As an example, we're going to style the menu bar in the eZ Components -color: indigo. The first step is to change the border around the menu, and -the background of the menu. We do that by overriding the following CSS:: +color: indigo. The first step is to tweak the border around the menu, and +the menu background. We do this by overriding the following CSS:: .yui-skin-sam .yuimenubar { border: 1px solid #55517b; @@ -598,15 +639,15 @@ } We also need to change the color of the arrow on the -right side of each menu for non-selected menu items to white. The YUI uses a +right side of each non-selected menu item to white. The YUI uses a special trick for rendering images. Instead of having a -small image file for each element, they instead use what is called a "sprite" -file, which is one image with all of the images laid out on a grid for all of -the elements. From this they just cut out the part they -need. Some information about this technique can be found here__. As we want -to change the arrow images, we created our own sprite file to be used for those two -elements. The sprite file can be found here__. The CSS below places the images -in the correct position:: +small image file for each element, it uses what is called a "sprite" +file, which is one image with all of the images for all of +the elements laid out on a grid. From this, the needed part for each element is +specified in the CSS. Some information about this technique can be found +here__. We created our own sprite file, which can be found here__. The CSS +below specifies the correct position within the image for each element's +image:: .yui-skin-sam .yuimenubarnav .yuimenubaritemlabel .submenuindicator { background-position:5px -21px; @@ -640,14 +681,14 @@ .. image:: ../../images/articles/2007-12-20-menu3.png -All the CSS overrides from above can be found in the "ezc.css" file in the -examples download. We still need to hook it into the HTML file, which -we do by adding the following line after the existing stylesheet +All the CSS overrides from above can be found in the ``ezc.css`` file in the +downloadable archive. We still need to hook the CSS files into the HTML file, +which we do by adding the following line after the existing stylesheet line for the default YUI styles:: <link rel="stylesheet" type="text/css" href="ezc.css"/> -The full example can be found in the downloadable archive (see left menu) with +The full example can be found in the downloadable archive (see the left menu) with examples with the filename ``full2.php``. Conclusion @@ -658,8 +699,8 @@ the plain text renderer, we generated output suitable for display on a console. Then, we used the Tree component's YUI visualizer to generate XHTML content from the same data. The XHTML content can be processed by the YUI library to -produce a menu for a website. From there, we explored how to customimze the -style of the the menu widget. +produce a website menu. From there, we explored how to customize the +style of the menu widget. Resources ========= -- svn-components mailing list svn-components@lists.ez.no http://lists.ez.no/mailman/listinfo/svn-components