Wednesday, April 22, 2009

Targeting Nested LI's with jQuery

After two days of trying every DOM hierarchy transversile that I could think of or learn from I was about to give up. The task at hand was fairly simple. I was creating a TreeView menu for a given directory. The top level nodes where generated when the page loads and if the top level "resource" is a directory then when that item is clicked an AJAX call is made to get it's sub-resources which are nested ul/li.

In order to make subsequent calls for any directories/files that are > the first level I need to get the id of the li tag that is clicked (only directories have the ability to be clicked).

I thought I would be able to navigate through the DOM hiearchy to the nested li and retrieve the id, however, this becomes a problem with nested ul/li's because if you try to alert the id and expect the result to be of the nested element you will get the id of the parent element.

List Items


  • [+]applications


    • lib
    • index.php
    • settings
    • .htaccess
    • images
    • css
    • views
    • js
    • modules
    • layouts
  • [+]ops

// doesn't work

$(document).ready(function() {

$("li").click(function() {
alert($(this).attr('id'));

})
});


// does work
$(document).ready(function() {

$("li").click(function(event) {
alert(event.target.id);

})
});


The solution was to pass and event object to the click event handler. After I figured out that little nugget it only took me another hour to finish up my script.

Sunday, April 5, 2009

Zend Framework Dynamic Site

::UPDATE - 04.09.2009::
I finally was able to create an example of the below described site.  If you have any questions/comments please let me know.

When creating a website, especially in the corporate/enterprise world, it assumed that you have to use some sort of content management system.  The range, and subsequent debate, could be everything from free (Joomla, Wordpress, Drupal) to the very expensive (Vignette).  While I am in a firm believer in the use of a CMS it seems lately I have been asked to develop sites whose content doesn't change that often, but the responsibility still needs to fall into the hands of a content editor not a developer.  In addition, the designer that I work with wanted the freedom of creating as many templates as he wanted and tweak the design without having to consult me, the developer, nor have to work with a content editor to update any of the content pages.

I went back and forth how to best solve this solution.  While Joomla and Wordpress would have certainly handled all of these requirements there is the overhead that comes with any CMS and with the requirements that I had to work with I kept asking myself if using a CMS was lighting a grill with an atom bomb.

The end result was a hybrid between using static "html" and a mini-CMS....all using the Zend Framework.  I came up with a way that separated the content, layouts, and the developer maintained backedend of the site.

Basic requirements:
  1. SEF's
  2. Breadcrumb subheadings
  3. Flexible layouts - some pages might need a "one column content well", "one column content well with a side bar", etc
  4. Content pages should be kept in one location
  5. Templates should be independent of backend code and content
Directory Structure:
  • content
  • css
  • images
  • index.php
  • js
  • layouts
  • lib
  • modules
  • settings
How It Works
  • Creating/Editing Content


    1. Create the static phtml file in the content directory
    2. Edit the content.xml file in the content directory and add the following attributes and/or nodes: url - 1) what the request url will be. 2) file - the name of the phtml file (minus the extension). 3) pageTitle - self explainatory 4) layout - what template do you want to use for the page
  • Page Rendering


    1. Zend Layout
    2. Zend MVC
    3. Custom regex route
    4. Custom Site Page Render Plugin

Plugin and Go

The majority of the site dynamics happens in the custom plugin - routeShutdown method.
  1. Based upon the $_SERVER['REQUEST_URI'] the appropriate "page" node is located: "//pages/page[@url='{$_SERVER['REQUEST_URI']}']".
  2. The page title is set
  3. The name of the view (phtml) file is set
  4. The breadcrumbs array is populated. *
  5. All the attributes are then set as an array of params and set in the request.
  6. The IndexController/indexAction grabs the params, sets them to view properties to be displayed in the layout

*::NOTE::
Since there is technically not a hierarchy of files on the web server... the way that the url is decided upon is by the content editors.  Because of this there is a business rule in place that the "toplevel" navigation is the first set of characters in the url and child navigation thus follows.  In the method the breadcrumbs are created by parsing this pattern.

Conclusion
While there is definite room for improvement to how the site management is done we have seen great efficiency not only how the site is maintained and content is created, but also the amount of code that is used to generate the site.
  • 1 module, 1 controller, 1 action, 1 custom plugin
  • developers, content editors, and designers are able to work on their respective portions of the site without having to rework or update any other aspect of the site in 99% of use cases.

I finally was able to create an example of the below described site.  If you have any questions/comments please let me know.