From ba9b0e647bff1bf0c437ab204ddf11783ed698f8 Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Fri, 1 May 2009 10:26:57 +0000 Subject: Merge "c-free" branch to trunk. --- docs/tutorials/lxmlgraph/step02.rst | 132 ------------------------------------ 1 file changed, 132 deletions(-) delete mode 100644 docs/tutorials/lxmlgraph/step02.rst (limited to 'docs/tutorials/lxmlgraph/step02.rst') diff --git a/docs/tutorials/lxmlgraph/step02.rst b/docs/tutorials/lxmlgraph/step02.rst deleted file mode 100644 index 1dc1ebcd3..000000000 --- a/docs/tutorials/lxmlgraph/step02.rst +++ /dev/null @@ -1,132 +0,0 @@ -================================================ -Step 2: Hello World as XML -================================================ - -We now have a project named ``lxmlgraph``. It contains a *package* -(also) named ``lxmlgraph``. - -In this step we will add an XML document to the *package* as our model -data. We will leverage the following :mod:`repoze.bfg` machinery: - - - Model data with interfaces that define "types" - - - ZCML configuration to provide type-specific views - -Our application will need to do these things: - - - Use :term:`lxml` Element classes to inject :mod:`repoze.bfg` - behavior into ``lxml`` nodes - - - That model class needs to implement the :mod:`repoze.bfg` - publishing contract - -All of the below filenames are relative to the ``lxmlgraph`` *package* -rather than the *project*. - -``samplemodel.xml`` ------------------------------------ - -We're going to add an XML document that will serve as a source for -model data named ``samplemodel.xml``. Put the content of this file in -your package: - -.. literalinclude:: step02/myapp/samplemodel.xml - :linenos: - :language: xml - -#. Line 2 provides the root of the model as an XML ```` node. - The element name doesn't have to be ````. It has a name of - ``site``. - -#. In lines 3-4, the ```` contains 2 top-level children: a and - b. These are provided as an element name ````. This, - also, is meaningless as far as :mod:`repoze.bfg` is concerned. - However, this is where you compose the information model you are - publishing. - -The only special constraint is that an XML node that wants to be -"found" by :mod:`repoze.bfg` in during traversal *must* have a -``name`` attribute. (The use of ``@name`` corresponds to ``__name__`` -in the :mod:`repoze.bfg` sense of :term:`location` ). Each hop in the -URL tries to grab a child with an attribute matching the next hop. -Also, the value of the ``@name`` should be unique in its containing -node. - -Module ``models.py`` ------------------------------- - -At a high level, we make write a class that "extends" ``lxml`` -``Element`` nodes, create an ``lxml`` parser, and register the custom -class with the parser. Replace the contents of the autogenerated -``models.py`` with the content we show below. - -.. literalinclude:: step02/myapp/models.py - :linenos: - -#. Line 4 imports :term:`lxml`. - -#. Line 9 creates the custom class we are going to use to extend - etree.ElementBase. The ``_ has great documentation on the - various ways to inject custom Python behavior into XML. - -#. Just as before, line 12 says that instances of this class support a - certain content type (interface.) In our case, instances will be - XML nodes. - -#. :mod:`repoze.bfg` has a protocol where model data should have an - ``__name__`` attribute. Lines 14-16 implement this by grabbing the - ``@name`` attribute of the current node. - -#. URL traversal in :mod:`repoze.bfg` works via the ``__getitem__`` - protocol. Thus, we need a method that implements this. Lines - 18-26 use XPath to look for a direct child that has an ``@name`` - matching the item name that's being traversed to. If it finds it, - return it. If not, or if more than one is found, raise an error. - -#. As before, ``get_root`` is the function that is expected to return - the top of the model. In lines 30+ we do the :term:`lxml` magic to - get the custom Python class registered. We then load some XML and - return the top of the tree. - -Module ``views.py`` ------------------------------ - -Replace the autogenerated ``views.py`` code in the ``lxmlgraph`` -package with the following: - -.. literalinclude:: step02/myapp/views.py - :linenos: - -Here's what that file does: - -#. Line 5 grabs the element name (tag name) of the ``context``, which - is the current XML node that we're traversing through. - -#. Line 6 uses the special property we defined in our custom Python - class to get the ``__name__`` of the context. - -We don't need to change the ``configure.zcml`` because the -autogenerated one is still correct for this configuration. It -includes: - -.. literalinclude:: step02/myapp/configure.zcml - :linenos: - :language: xml - -Browsing the Model ------------------------- - -We're done changing code. Start the application by executing ``paster -serve lxmlgraph.ini`` (the ``.ini`` file is in the project directory). -It will listen on port 5432. We can use these URLs to browse the -model graph and see results:: - - http://localhost:5432/a (Hello to document from a @ /a) - - http://localhost:5432/b (Hello to document from b @ /b) - - http://localhost:5432/c (Not Found) - -In this case, each request grabs a node in the XML and uses it as the -data for the view. -- cgit v1.2.3