Changeset 3105:9c7bf70b7def in livinglogic.python.xist

Show
Ignore:
Timestamp:
01/04/08 19:09:56 (12 years ago)
Author:
Walter Doerwald <walter@…>
Branch:
default
Message:

Drop old example. Explain conversion targets.

Files:
1 modified

Legend:

Unmodified
Added
Removed
  • docs/Advanced.xml

    r3104 r3105  
    9696 
    9797    def convert(self, converter): 
    98         e = html.a(self.content, self.attrs, target="_top") 
    99         return e.convert(converter) 
     98        node = html.a(self.content, self.attrs, target="_top") 
     99        return node.convert(converter) 
    100100</prog> 
    101101</example> 
     
    125125 
    126126 
    127 <!-- 
    128 <par>Each element class that belongs to a namespace can access its 
    129 namespace via the class attribute <lit>__ns__</lit>. When you're subclassing 
    130 namespace classes, the elements in the base namespace will be automatically 
    131 subclassed too. Of course you can explicitly subclass an element class too. 
    132 The following example shows the usefulness of this feature. Define your base 
    133 namespace like this and put it into <filename>navns.py</filename>:</par> 
    134  
    135 <prog> 
    136 from ll.xist import xsc 
    137 from ll.xist.ns import html 
    138  
    139 languages = [ 
    140     (u"Python", u"http://www.python.org/"), 
    141     (u"Perl", u"http://www.perl.org/"), 
    142     (u"PHP", u"http://www.php.net/"), 
    143     (u"Java", u"http://java.sun.com/") 
    144 ] 
    145  
    146 class navigation(xsc.Element): 
     127<section><title>Conversion targets</title> 
     128 
     129<par>The <arg>converter</arg> argument passed to the <method>convert</method> 
     130method has an attribute <lit>target</lit> which is a module or pool and 
     131specifies the target namespace to which <self/> should be converted.</par> 
     132 
     133<par>You can check which conversion is wanted by checking e.g. the 
     134<lit>xmlns</lit> atribute. Once this is determined you can use element classes 
     135from the target to create the required &xml; object tree. This makes it possible 
     136to customize the conversion by passing a chained pool to the 
     137<method>convert</method> method that extends an existing namespace.</par> 
     138 
     139<par>The following example shows how an element be converted to two 
     140different targets:</par> 
     141 
     142<example><title>Using conversion targets</title> 
     143<prog> 
     144from ll.xist import xsc 
     145from ll.xist.ns import html, fo 
     146 
     147class bold(xsc.Element): 
    147148    def convert(self, converter): 
    148         node = self.__ns__.links() 
    149         for (name, url) in languages: 
    150             node.append(self.__ns__.link(name, href=url)) 
     149        if converter.target.xmlns == html.xmlns: 
     150            node = converter.target.b(self.content) 
     151        elif converter.target.xmlns == fo.xmlns: 
     152            node = converter.target.inline(self.content, font_weight="bold") 
     153        else: 
     154            raise TypeError("unsupported conversion target %r" % converter.target) 
    151155        return node.convert(converter) 
    152  
    153 class links(xsc.Element): 
    154     def convert(self, converter): 
    155         node = self.content 
    156         return node.convert(converter) 
    157  
    158 class link(xsc.Element): 
    159     class Attrs(xsc.Element.Attrs): 
    160         class href(xsc.URLAttr): pass 
    161  
    162     def convert(self, converter): 
    163         node = html.div(html.a(self.content, href=self[u"href"])) 
    164         return node.convert(converter) 
    165  
    166 class __ns__(xsc.Namespace): 
    167     xmlname = "nav" 
    168     xmlurl = "http://www.example.com/nav" 
    169 __ns__.makemod(vars()) 
    170 </prog> 
    171  
    172 <par>This namespace defines a navigation element that generates <class>div</class>s 
    173 with links to various homepages for programming languages. We can use it like this:</par> 
     156</prog> 
     157</example> 
     158 
     159<par>The default target for conversion is <module>ll.xist.ns.html</module>. 
     160Other targets can be specified via the <arg>target</arg> argument in the 
     161<class>Converter</class> constructor or the <method>conv</method> method:</par> 
     162 
    174163<tty> 
    175 <prompt>&gt;&gt;&gt; </prompt><input>import navns</input> 
    176 <prompt>&gt;&gt;&gt; </prompt><input>print navns.navigation().conv().bytes()</input> 
    177 &lt;div&gt;&lt;a href="http://www.python.org/"&gt;Python&lt;/a&gt;&lt;/div&gt; 
    178 &lt;div&gt;&lt;a href="http://www.perl.org/"&gt;Perl&lt;/a&gt;&lt;/div&gt; 
    179 &lt;div&gt;&lt;a href="http://www.php.net/"&gt;PHP&lt;/a&gt;&lt;/div&gt; 
    180 &lt;div&gt;&lt;a href="http://java.sun.com/"&gt;Java&lt;/a&gt;&lt;/div&gt; 
     164<prompt>>>> </prompt><input>from ll.xist.ns import html, fo</input> 
     165<prompt>>>> </prompt><input>import foo</input> # This is the code from above 
     166<prompt>>>> </prompt><input>print foo.bold("foo").conv().bytes()</input> 
     167<![CDATA[<b>foo</b>]]> 
     168<prompt>>>> </prompt><input>print foo.bold("foo").conv(target=html).bytes()</input> 
     169<![CDATA[<b>foo</b>]]> 
     170<prompt>>>> </prompt><input>print foo.bold("foo").conv(target=fo).bytes()</input> 
     171<![CDATA[<inline font-weight="bold">foo</inline>]]> 
    181172</tty> 
    182 <par>(Of course the output will all be on one line.)</par> 
    183  
    184 <par>Now we can define a derived namespace (in the file <filename>nav2ns.py</filename>) 
    185 that overwrites the element classes <class>links</class> and <class>link</class> 
    186 to change how the navigation looks:</par> 
    187  
    188 <prog> 
    189 from ll.xist import xsc 
    190 from ll.xist.ns import html 
    191  
    192 import navns 
    193  
    194 class __ns__(navns): 
    195     class links(navns.links): 
    196         def convert(self, converter): 
    197             node = html.table( 
    198                 self.content, 
    199                 border=0, 
    200                 cellpadding=0, 
    201                 cellspacing=0, 
    202                 class_=u"navigation", 
    203             ) 
    204             return node.convert(converter) 
    205  
    206     class link(navns.link): 
    207         def convert(self, converter): 
    208             node = html.tr( 
    209                 html.td( 
    210                     html.a( 
    211                         self.content, 
    212                         href=self[u"href"], 
    213                     ) 
    214                 ) 
    215             ) 
    216             return node.convert(converter) 
    217 __ns__.makemod(vars()) 
    218 </prog> 
    219  
    220 <par>When we use the navigation element from the derived namespace we'll get 
    221 the following output:</par> 
    222  
    223 <tty> 
    224 <prompt>&gt;&gt;&gt; </prompt><input>import nav2ns</input> 
    225 <prompt>&gt;&gt;&gt; </prompt><input>print nav2ns.navigation().conv().bytes()</input> 
    226 &lt;table border="0" cellpadding="0" cellspacing="0" class="navigation"&gt; 
    227 &lt;tr&gt;&lt;td&gt;&lt;a href="http://www.python.org/"&gt;Python&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt; 
    228 &lt;tr&gt;&lt;td&gt;&lt;a href="http://www.perl.org/"&gt;Perl&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt; 
    229 &lt;tr&gt;&lt;td&gt;&lt;a href="http://www.php.net/"&gt;PHP&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt; 
    230 &lt;tr&gt;&lt;td&gt;&lt;a href="http://java.sun.com/"&gt;Java&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt; 
    231 &lt;/table&gt; 
    232 </tty> 
    233 <par>(again all on one line.)</par> 
    234  
    235 <par>Notice that we automatically got an element class <class>nav2ns.navigation</class>, 
    236 that this element class inherited the <method>convert</method> method from its 
    237 base class and that the call to <method>convert</method> on the derived class 
    238 did instantiate the link classes from the derived namespace.</par> 
    239  
    240 </section> 
    241  
    242  
    243 <section><title>Namespaces as conversion targets</title> 
    244  
    245 <par>The <arg>converter</arg> argument passed to the <method>convert</method> method 
    246 has an attribute <lit>target</lit> which is a namespace class and specifies the target 
    247 namespace to which <self/> should be converted.</par> 
    248  
    249 <par>You can check which conversion is wanted with <function>issubclass</function>. 
    250 Once this is determined you can use element classes from the target to create the 
    251 required &xml; object tree. This makes it possible to customize the conversion by 
    252 passing a derived namespace to the <method>convert</method> method. To demonstrate 
    253 this, we change our example namespace to use the conversion target like this:</par> 
    254  
    255 <prog> 
    256 import navns 
    257  
    258 class __ns__(navns): 
    259     class links(navns.links): 
    260         def convert(self, converter): 
    261             node = converter.target.table( 
    262                 self.content, 
    263                 border=0, 
    264                 cellpadding=0, 
    265                 cellspacing=0, 
    266                 class_=u"navigation", 
    267             ) 
    268             return node.convert(converter) 
    269  
    270     class link(navns.link): 
    271         def convert(self, converter): 
    272             target = converter.target 
    273             node = target.tr( 
    274                 target.td( 
    275                     target.a( 
    276                         self.content, 
    277                         href=self[u"href"], 
    278                     ) 
    279                 ) 
    280             ) 
    281             return node.convert(converter) 
    282 </prog> 
    283  
    284 <par>What we might want to do is have all links (i.e. all <class>ll.xist.ns.html.a</class> 
    285 elements) generated with an attribute <lit>target="_top"</lit>. For this we derive 
    286 a new namespace from <class>ll.xist.ns.html</class> and overwrite the <class>a</class> 
    287 element:</par> 
    288  
    289 <prog> 
    290 from ll.xist.ns import html 
    291  
    292 class __ns__(html): 
    293     class a(html.a): 
    294         def convert(self, converter): 
    295             node = html.a(self.content, self.attrs, target=u"_top") 
    296             return node.convert(converter) 
    297 </prog> 
    298  
    299 <par>Now we can pass this namespace as the conversion target and all links 
    300 will have a <lit>target="_top"</lit>.</par> 
    301 </section> 
    302 --> 
     173</section> 
     174 
    303175 
    304176<section><title>Validation and content models</title>