Changes between Version 1 and Version 2 of EggCookingTutorialTrac0.11


Ignore:
Timestamp:
Jun 3, 2007 10:57:00 AM (7 years ago)
Author:
khundeen
Comment:

--

Legend:

Unmodified
Added
Removed
Modified
  • EggCookingTutorialTrac0.11

    v1 v2  
    1 [[TOC]] 
    2  
    3 = Egg cooking = 
     1[[TOC(EggCookingTutorialTrac0.11)]] 
     2 
     3= Basic Egg cooking = 
    44 
    55Since Trac 0.11, Genshi is used as the new template engine.  Some APIs have also been changed. 
     
    104104During development you can run the command {{{python setup.py develop}}} in the directory where you created it.  This way you don't need to do it every time you change the code. Check [trac:TracDev/PluginDevelopment] for more deployment options. 
    105105 
     106Edit the conf/trac.ini file by adding {{{helloworld.* = enabled}}} in the {{{[components]}}} section. 
     107 
    106108Restart the trac server.  If you're using mod_python you have to restart Apache. 
    107109 
     
    112114Now you have successfully created your first egg. You can continue further to learn how to use templates in your plugins, and make its output look like other Trac pages. 
    113115 
     116= Cook even better eggs = 
     117 
     118After you read [wiki:EggCookingTutorialTrac0.11#BasicEggcooking Basic Egg Cooking] and created your first egg, it's time to make it a bit better. 
     119 
     120First we integrate our output to other Trac layout in form of Genshi template. 
     121 
     122== Adding template == 
     123 
     124To have a template we need a directory and of course the template itself. We will keep the same simple "Hello world!" text, but this time we will integrate our fine words into a Trac layout. 
     125 
     126For that we need to create one additional directory: 
     127{{{ 
     128./helloworld-plugin/helloworld/templates/ 
     129}}} 
     130 
     131In that directory create a new file ''helloworld.html'': 
     132{{{ 
     133#!text/html 
     134<!DOCTYPE html 
     135    PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" 
     136    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> 
     137<html xmlns="http://www.w3.org/1999/xhtml" 
     138      xmlns:py="http://genshi.edgewall.org/" 
     139      xmlns:xi="http://www.w3.org/2001/XInclude"> 
     140  <xi:include href="layout.html" /> 
     141  <head> 
     142    <title>Helloworld</title> 
     143  </head> 
     144 
     145  <body> 
     146    <div id="ctxtnav" class="nav"></div> 
     147 
     148    <div id="content" class="helloworld"> 
     149      <h1>Hello World!</h1> 
     150    </div> 
     151  </body> 
     152</html> 
     153}}} 
     154 
     155Now you have created the template for the plugin.  
     156 
     157== Tell Trac where template is == 
     158 
     159Trac doesn't know where your template is so you have to tell it. This is done by implementing the ITemplateProvider interface in ''helloworld.py''. 
     160 
     161So you change few lines as following: 
     162 
     163Line 7 is changed from 
     164{{{ 
     165#!python 
     166from trac.web.chrome import INavigationContributor 
     167}}} 
     168to 
     169{{{ 
     170#!python 
     171from trac.web.chrome import INavigationContributor, ITemplateProvider 
     172}}} 
     173 
     174Line 10 is changed from 
     175{{{ 
     176#!python 
     177    implements(INavigationContributor, IRequestHandler) 
     178}}} 
     179{{{ 
     180#!python 
     181    implements(INavigationContributor, IRequestHandler, ITemplateProvider) 
     182}}} 
     183 
     184Starting from line 24 old ''process_request'' method is replaced by 
     185{{{ 
     186#!python 
     187    def process_request(self, req): 
     188        data = {}         
     189        # This tuple is for Genshi (template_name, data, content_type) 
     190        # Without data the trac layout will not appear. 
     191        return 'helloworld.html', data, None 
     192}}} 
     193 
     194And to end of file you need to tell where your template is located 
     195{{{ 
     196#!python 
     197    # ITemplateProvider methods 
     198    # Used to add the plugin's templates and htdocs  
     199    def get_templates_dirs(self): 
     200        from pkg_resources import resource_filename 
     201        return [resource_filename(__name__, 'templates')] 
     202}}} 
     203 
     204Complete version of ''helloworld.py'': 
     205{{{ 
     206#!python 
     207# Helloworld plugin 
     208 
     209import re 
     210 
     211from genshi.builder import tag 
     212 
     213from trac.core import * 
     214from trac.web import IRequestHandler 
     215from trac.web.chrome import INavigationContributor, ITemplateProvider 
     216 
     217class HelloWorldPlugin(Component): 
     218    implements(INavigationContributor, IRequestHandler, ITemplateProvider) 
     219 
     220    # INavigationContributor methods 
     221    def get_active_navigation_item(self, req): 
     222        return 'helloworld' 
     223 
     224    def get_navigation_items(self, req): 
     225        yield ('mainnav', 'helloworld', 
     226               tag.a('Hello World', href=req.href.helloworld())) 
     227 
     228    # IRequestHandler methods 
     229    def match_request(self, req): 
     230        return re.match(r'/helloworld(?:_trac)?(?:/.*)?$', req.path_info) 
     231 
     232    def process_request(self, req): 
     233        data = {}         
     234        # This tuple is for Genshi (template_name, data, content_type) 
     235        # Without data the trac layout will not appear. 
     236        return 'helloworld.html', data, None 
     237 
     238    # ITemplateProvider methods 
     239    # Used to add the plugin's templates and htdocs  
     240    def get_templates_dirs(self): 
     241        from pkg_resources import resource_filename 
     242        return [resource_filename(__name__, 'templates')] 
     243}}} 
     244 
     245== Copy template to egg == 
     246 
     247Finally you have to include the new template directory in an egg. 
     248 
     249So change ''setup.py'' to be like: 
     250{{{ 
     251#!python 
     252from setuptools import find_packages, setup 
     253 
     254# name can be any name.  This name will be used to create .egg file. 
     255# name that is used in packages is the one that is used in the trac.ini file. 
     256# use package name as entry_points 
     257setup( 
     258    name='Trachelloworld', version='1.1', 
     259    packages=find_packages(exclude=['*.tests*']), 
     260    entry_points = """ 
     261        [trac.plugins] 
     262        helloworld = helloworld 
     263    """, 
     264    package_data={'helloworld': ['templates/*.html']}, 
     265) 
     266}}} 
     267 
     268== Building and deploying == 
     269 
     270Building and deployment goes exactly the same as it did in the previous section [wiki:EggCookingTutorialTrac0.11#Firstdeployment First Deployment]. 
     271 
     272Now you should see a big "Hello world!" integrated into your Trac layout when you press that fancy button in the main navigation bar. 
     273 
     274== Aftermath == 
     275 
     276Now that you have added a basic template for your plugin let's add the final twist, putting some static content like a stylesheet and an image. Continue to [wiki:EggCookingTutorialTrac0.11#] 
     277 
    114278 
    115279[[TagIt(khundeen)]]