Skip to end of metadata
Go to start of metadata

<ac:macro ac:name="unmigrated-inline-wiki-markup"><ac:plain-text-body><![CDATA[

<ac:macro ac:name="unmigrated-inline-wiki-markup"><ac:plain-text-body><![CDATA[

Zend Framework: Zend_View_Helper_Dojo Component Proposal

Proposed Component Name Zend_View_Helper_Dojo
Developer Notes http://framework.zend.com/wiki/display/ZFDEV/Zend_View_Helper_Dojo
Proposers Matthew Weier O'Phinney
Zend Liaison TBD
Revision 1.0 - 27 May 2008: Initial Draft. (wiki revision: 5)

Table of Contents

1. Overview

Using dojo requires a number of view integration points; these include requiring the dojo.js file itself, dojo.require calls, loading appropriate stylesheets, etc. ZF should make including these as easy as possible.

2. References

3. Component Requirements, Constraints, and Acceptance Criteria

  • MUST be a single view helper with multiple methods
  • MUST be able to render as string
  • MUST have methods for setting dojo include metadata
    • MUST support using via CDN, using specified version
      • SHOULD allow specifying either AOL or Google as CDN
    • MUST support using local install, via path
    • MUST allow specifying djConfig key/value pairs
    • SHOULD default to CDN if no path specified
  • MUST have method for requiring components
    • MUST have method for specifying module paths
  • MUST emit default dojo.js stylesheet
    • SHOULD default to CDN location if no path specified
    • MUST allow specifying CDN version
    • MUST allow specifying dojo install location by local path
    • MUST allow specifying dijit themes by module

4. Dependencies on Other Framework Components

  • Zend_View_Exception
  • Zend_View_Helper_Placeholder

5. Theory of Operation

This component provides a fluent, PHP5 interface for programmatically setting up your Dojo environment within your view scripts. You may specify whether Dojo loads from a local path or the AOL CDN, paths to any custom modules, stylesheet modules to use, and more. Within your layout script, you will then echo the placeholder to setup the appropriate style and script tags based on the settings provided.

6. Milestones / Tasks

  • Milestone 1: [DONE] Prepare API
  • Milestone 2: Publish this proposal
  • Milestone 3: Complete first working code and tests
  • Milestone 4: Write documentation

7. Class Index

  • Zend_View_Helper_Dojo

8. Use Cases

UC-01

require a dojo component:

UC-02

register a module path

UC-03

tell dojo to use the CDN, version 1.0

UC-03a

tell dojo to use the Google CDN

UC-04

tell dojo to use local install

UC-05

tell dojo to parse on load

UC-06

specify a stylesheet by module notation

UC-07

require a custom stylesheet

UC-08

specify a function to run onLoad

UC-09

specify an object method to run onLoad

UC-10

capture JS to use as a named callback to run onLoad

UC-11

enable dojo (minimally, loads dojo.js and dojo.css)

UC-12

disable dojo (will not enable any functionality when rendered)

UC-13

test if dojo is enabled

UC-14

echo the dojo requirements

9. Class Skeletons

]]></ac:plain-text-body></ac:macro>

]]></ac:plain-text-body></ac:macro>

Labels:
None
Enter labels to add to this page:
Please wait 
Looking for a label? Just start typing.
  1. May 27, 2008

    <p>I'd prefer enable()/disable() vs enableDojo() because of the redundancy</p>

  2. May 27, 2008

    <p>I would prefer enable()/disable() in preference to enableDojo()/disableDojo(). </p>

    <p>Similarly setDjConfig()/getDjConfig() would be easier as setConfig()/getConfig()</p>

    <p>Other than that, it looks good.</p>

    1. May 28, 2008

      <p>I'm agreeing with using enable() and disable(). However, setDjConfig()/getDjConfig() map to the djConfig object in Dojo, and thus need to retain their name.</p>

  3. May 27, 2008

    <p>Agreed, it would be much better if method names were not related to the class name. Using the generic names would provide better consistency in the future (or at least less annoyance) if other JS libraries are implemented.</p>

  4. May 27, 2008

    <p>I agree with on enable()/disable() and setConfig()/getConfig().</p>

    <p>When capturing:</p>

    <ac:macro ac:name="code"><ac:plain-text-body><![CDATA[
    <? $this->dojo()->onLoadCaptureStart('foo') ?>

    bar();

    baz();

    <? $this-.dojo()->onLoadCaptureStop('foo') ?>
    ]]></ac:plain-text-body></ac:macro>
    <p>What will this do, exactly? What is 'foo'? Will this put the captured content into a function called foo(), which is added to run in the onload() event, or will it set the captured content be the only thing run in onload()? What's going on here?</p>

    <p>Also, how is $this->dojo()->addStyleSheet('/css/custom.css') different from adding a style sheet using the HeadLink() view helper?</p>

    1. May 28, 2008

      <p>Yes, 'foo' will be a closure that is called by dojo's onload handler (which offers some functionality beyond the standard onLoad DOM event).</p>

      <p>Regarding addStyleSheet(), Dojo typically adds stylesheets using @import statements as follows:</p>
      <ac:macro ac:name="code"><ac:plain-text-body><![CDATA[
      <style type="text/css">
      @import "http://o.aolcdn.com/dojo/1.0.0/dijit/themes/tundra/tundra.css";
      @import "http://o.aolcdn.com/dojo/1.0.0/dojo/resources/dojo.css"
      </style>
      ]]></ac:plain-text-body></ac:macro>

      <p>addStyleSheet() would place an @import at the top of this stack to ensure that the various stylesheets are loaded in the appropriate order for cascading and to group the Dojo-specific stylesheet with other Dojo stylesheets.</p>

  5. May 27, 2008

    <p>Consistency aside, if there is not a good reason to expose the view variable as public, it should be protected to prevent contamination. Public variables in a loose-typed language such as PHP is a double-edged sword.</p>

    1. May 27, 2008

      <p>Yeah, why is the view public all over the framework?</p>

      1. May 28, 2008

        <p>Honestly, there's very little reason for it <em>not</em> to be public. Yes, it could bet "contaminated", but the chances of that happening are unlikely, and will, in fact, likely raise some pretty serious errors that will trickle up the error stack quickly.</p>

        <p>I have no problem making the view property protected, but this is a minor implementation detail at best.</p>

  6. May 28, 2008

    <p>I know it was announced after you created your proposal, but you may want to consider giving developers the option of getting Dojo through the <a href="http://code.google.com/apis/ajaxlibs/">AJAX Libraries API</a> instead of the AOL CDN if they'd prefer. I'm not sure how many Dojo developers would choose this over the AOL CDN, but if the proposed concept ends up being extended to other JavaScript libraries then I could see the AJAX Libraries API being very useful since it lets you access several different JavaScript libraries. </p>

    1. May 28, 2008

      <p>Funny – I just saw your comment after I updated the use cases and class skeletons to allow for this. <ac:emoticon ac:name="smile" /> See UC-03a for an example.</p>

      1. May 29, 2008

        <p>How do useCdn() and setCdn($cdn) relate?</p>

        <p>Maybe lose setCdn(), and change useCdn() to useCdn($cdn = 'aol'), where $cdn = false will result in not using a CDN.</p>

        <p>Isn't this kind of CDN logic a candidate for a sepparate component? We kind of know that other JavaScript frameworks will get a Zend component, most of which can be loaded from a CDN. Also, hardcoding CDN's to use might not be the proper way to go.<br />
        Besides this, Google also has the <a href="http://code.google.com/apis/ajaxlibs/documentation/">google.load()</a> API to load JavaScript libraries, which might be an interesting thing to add to Zend. </p>

        1. May 29, 2008

          <p>Good feedback. I've removed useCdn() from the class skeleton and use cases in favor of setCdn() with a sensible default. By default, the CDN is used unless setLocalPath() is called, so there is no reason to call setCdn(false). BTW, I'm only hardcoding CDNs that we know about and will support; we will allow passing an arbitrary CDN path as well, though this isn't shown in the use cases.</p>

          <p>Regarding the idea of separating the CDN logic to a separate component, I'll take it under consideration. Google's ajax libraries api is new, and I need to study it more to see if it's something we want to target in a generic fashion or not.</p>

  7. Jun 17, 2008

    <p>Shouldn't any CSS/javascript manipulation delegate to the already existing view helpers that deal with CSS/javascript?</p>

    1. Jun 17, 2008

      <p>I'm debating that issue currently as I work on the implementation. There are pros and cons to this:</p>

      <ul>
      <li>Pros
      <ul>
      <li>Keeps code DRY; not reimplementing functionality</li>
      <li>No need for additional helper calls in layout script</li>
      </ul>
      </li>
      <li>Cons
      <ul>
      <li>More difficult interactions for storing/retrieving data from the dojo view helper (needs to proxy)</li>
      <li>More difficult to trace when items were added to the other placeholders ("where did that come from?" types of situations)</li>
      </ul>
      </li>
      </ul>

      <p>Keep an eye on the incubator once the proposal is approved to see what the final decision is.</p>

      1. Jul 15, 2008

        <p>During implementation, it became very clear that the interactions between the dojo() view helper and the other placeholders would become very complex very quickly. In the end, I opted to keep all such functionality inside the dojo() view helper.</p>

        <p>In doing so, we've now identified that some functionality in the placeholder implementations may need to be extracted, such as the creation of arbitrary HTML elements. We will look into this for a future release.</p>

  8. Jun 23, 2008

    <ac:macro ac:name="note"><ac:parameter ac:name="title">Zend Official Response</ac:parameter><ac:rich-text-body>

    <p>This proposal is accepted to the Standard Incubator.</p>

    <p>Notes:</p>
    <ul>
    <li>Move development to Zend_Dojo top level namespace.</li>
    </ul>

    </ac:rich-text-body></ac:macro>

  9. Jul 03, 2008

    <p>Hi Matthew,</p>

    <p>I think, we need an additional support for the requirements of <a href="http://dojotoolkit.org/book/dojo-book-0-9/part-4-meta-dojo/package-system-and-custom-builds">DojoToolkit Builds</a>. Please look at the following Use Case:</p>

    <p>A developer has finished his Webapplication with DojoToolkit and decides to create a Custom Build of his DojoToolkit files, in order to speed up the loading time of his/her application. The DojoToolkit Build tool allows to aggregate DojoToolkit components into one or more layer (together with ShrinkSafe and such things...). The DojoToolkit folks has decided to use such layers with their new demos. One example is the <a href="http://turtle.dojotoolkit.org/~dante/skewDemo/demo.html">Demo from dante</a>, where you can find two lines in the <head>-section, in order to load</p>
    <ol>
    <li>dojo.js (with path src/release/dojo/dojo/dojo.js)</li>
    <li>demo.js (with path src/release/dojo/skew/demo.js)</li>
    </ol>

    <p>The result is, that only these two files are loaded by the Browser and not tons of individual .js file as you see, if you use a normal DojoToolkit installation without such a Build.</p>

    <p>That means, if a developer decides to use the DojoToolkit build tool, he/she needs the possibility to load more than one dojo.js file with the ViewHelper. The question is, if this is already considered with the current Proposal?</p>

    <p>Regards,</p>

    <p> Remi </p>

    1. Jul 03, 2008

      <p>I'll talk with dante about this; I think what we have scripted already should work, but I'll verify with him.</p>

      1. Jul 04, 2008

        <p>I'm in contact with dante about another problem: Is it possible to include the Dojo Build process into the Zend Framework? But this is far away from this proposal.</p>

        <p>So, back to the Zend_Dojo_View_Helper_Dojo: In the moment there is only the possiblity to set one local path with setLocalPath($path) and the _renderDojoScriptTag() method returns only one line</p>
        <ac:macro ac:name="code"><ac:plain-text-body><![CDATA[
        <script type="text/javascript" src="' . $source . '"></script>
        ]]></ac:plain-text-body></ac:macro>
        <p>But if you want to use a Dojo Build with one or more layers, you need more than this one line above. The example from Dante, I mentioned above, consists of two layers: dojo.js and demo.js and needs at least one more line in the <head>-section:<br class="atl-forced-newline" /></p>
        <ac:macro ac:name="code"><ac:plain-text-body><![CDATA[
        <script type="text/javascript" src="src/release/dojo/dojo/dojo.js"></script>
        <script type="text/javascript" src="src/release/dojo/skew/demo.js"></script>
         
        ]]></ac:plain-text-body></ac:macro>
        <p>This is only a simple example. If a developer decides to use more layers, he/she needs <em>n</em> script lines with individual paths in the <head>-section.</p>

        <p>One possible solution could be, to create a addLayer($path) method. Another idea could be to change the setLocalPath() method to accept an array instead of a string.</p>

        <p>Remi </p>

        1. Jul 15, 2008

          <p>Remi – addLayer() is now available in the incubator, and I have tested it locally with a custom build. It allows adding multiple layers, and generates a script tag for each.</p>

          1. Jul 15, 2008

            <p>There maybe a naming conflict with the addJavascriptFile()/getJavascriptFiles() of the jQuery proposal I currently write up. They actually provide the same functionality under different names. The question is, why the method name addLayer()/getLayers()? I can't really grasp the meaning of a layer in this relationsship.</p>

            <p>I also saw that there is a local relative path variable now, which allows for an implicit directory setting for all additional files and the stylesheet files. How should we generalize this? Should same directory as library be enforced on local path usage? Then i could drop my setJavascriptDirectory() methods in favour of an implicit relative directory detection.</p>

            1. Jul 15, 2008

              <p>Dojo builds can create what are called 'layers' – they contain the original dependencies, intern any static templates, and pass them through shrinksafe; they can be in a directory relative to Dojo, or in their own tree. Typically they ship with a stripped dojo distribution as well. Basically, the term is very specific to Dojo, and the mechanics can be different than simply loading a javascript file (though that is the current implementation).</p>

              <p>We could potentially have addJavascriptFile and family in an abstract class or interface; there's no reason that functionality could not be included with the dojo helper as well.</p>

              <p>The local relative directory path is autodiscovered based on the location of the dojo file.This is used to help load stylesheet resources, which follow a particular naming convention; this allows us to utilize notation like 'dijit.themes.tundra' and have it resolve to the appropriate file (../dijit/themes/tundra/tundra.css, relative to the dojo/ directory). If you have your toolkit library in a different tree than other JS files, this relative path may be inaccurate.</p>