Changeset 711

Show
Ignore:
Timestamp:
04/24/06 16:58:28 (3 years ago)
Author:
pacopablo
Message:

TraciStanPlugin:

  • Ready for major testing.
  • Includes a render function called includeCS that allows for ClearSilver templates to be included.
  • Includes example plugin to show usage and how to integrate with the normal trac look.
Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • tracistanplugin/0.10/example/aftracistan/aftracistan/htdocs/css/aftracistan.css

    r694 r711  
    33Version: 1.1, November 28, 2005 */ 
    44 
    5 body
     5#divbody
    66background:#e0e0e0 url(../img/bodybg.gif) repeat-x; 
    7 color:#505050; 
    8 font:76% Georgia,Verdana,Tahoma,Arial,sans-serif; 
    97margin:0; 
    108padding:0; 
     
    1210} 
    1311 
    14 p{ 
     12#divbody p{ 
    1513line-height:1.5em; 
    1614margin:0 0 15px; 
    17 
    18  
    19 a{ 
     15color:#505050 ! important; 
     16font:76% Georgia,Verdana,Tahoma,Arial,sans-serif ! important; 
     17
     18 
     19#divbody a{ 
    2020color:#fa9035; 
    2121font-weight:700; 
     
    2323} 
    2424 
    25 a:hover{ 
     25#divbody a:hover{ 
    2626color:#d04a10; 
    2727} 
    2828 
    29 hr{ 
     29#divbody hr{ 
    3030height:1px; 
    3131margin:10px 0; 
     
    3333} 
    3434 
    35 dt{ 
     35#divbody dt{ 
    3636font-weight:700; 
    3737} 
    3838 
    39 dd{ 
     39#divbody dd{ 
    4040margin:1px 0 12px 15px; 
    4141} 
    4242 
    43 #container{ 
     43#divbody #container{ 
    4444background:#c0c0c0 url(../img/bodybg.gif) repeat-x; 
    4545margin:0 auto; 
     
    4848} 
    4949 
    50 #sitename{ 
     50#divbody #sitename{ 
    5151background:url(../img/leaves.jpg) top center no-repeat; 
    5252color:#ffffff; 
     
    5757} 
    5858 
    59 #sitename h1{ 
     59#divbody #sitename h1{ 
    6060font-size:2.2em; 
    6161margin:0; 
     
    6363} 
    6464 
    65 #sitename span{ 
     65#divbody #sitename span{ 
    6666font-size:1.6em; 
    6767letter-spacing:-1px; 
     
    6969} 
    7070 
    71 #nav{ 
     71#divbody #nav{ 
    7272background:url(../img/greypx.gif) bottom left repeat-x; 
    7373float:left; 
     
    7575} 
    7676 
    77 #nav ul{ 
     77#divbody #nav ul{ 
    7878list-style:none; 
    7979margin:0; 
     
    8181} 
    8282 
    83 #nav a{ 
     83#divbody #nav a{ 
    8484background:url(../img/tabs.gif) no-repeat 100% 0; 
    8585color:#808080; 
     
    9191} 
    9292 
    93 #nav a:hover{ 
    94 color:#505050; 
    95 } 
    96  
    97 #nav li{ 
     93#divbody #nav a:hover{ 
     94color:#505050; 
     95} 
     96 
     97#divbody #nav li{ 
    9898background:url(../img/tabs.gif) no-repeat 0 0; 
    9999float:left; 
     
    102102} 
    103103 
    104 #nav #current{ 
     104#divbody #nav #current{ 
    105105background:url(../img/tabs.gif) no-repeat 0 -41px; 
    106106} 
    107107 
    108 #nav #current a{ 
     108#divbody #nav #current a{ 
    109109background:url(../img/tabs.gif) no-repeat 100% -41px; 
    110110color:#303030; 
     
    112112} 
    113113 
    114 #wrap1{ 
     114#divbody #wrap1{ 
    115115background:#ffffff url(../img/innerbg.gif) repeat-y; 
    116116border-bottom:1px solid #808080; 
     
    122122} 
    123123 
    124 #wrap2{ 
     124#divbody #wrap2{ 
    125125background:url(../img/header.jpg) top left no-repeat; 
    126126padding:10px; 
     
    128128} 
    129129 
    130 #header{ 
     130#divbody #header{ 
    131131height:30px; 
    132132position:relative; 
     
    134134} 
    135135 
    136 #header h1{ 
     136#divbody #header h1{ 
    137137float:left; 
    138138font-size:1.4em; 
     
    141141} 
    142142 
    143 #topbox{ 
     143#divbody #topbox{ 
    144144color:#808080; 
    145145margin:0 0 4px; 
     
    147147} 
    148148 
    149 #topbox a{ 
     149#divbody #topbox a{ 
    150150color:#d04a10; 
    151151} 
    152152 
    153 #topbox a:hover{ 
     153#divbody #topbox a:hover{ 
    154154text-decoration:underline; 
    155155} 
    156156 
    157 #leftside{ 
     157#divbody #leftside{ 
    158158float:left; 
    159159margin:-15px 0 0; 
     
    161161} 
    162162 
    163 #leftside h1{ 
     163#divbody #leftside h1{ 
    164164font-size:1.4em; 
    165165font-weight:400; 
    166166} 
    167167 
    168 #rightside{ 
     168#divbody #rightside{ 
    169169float:right; 
    170170margin:40px 15px 20px 0; 
     
    172172} 
    173173 
    174 #rightside h1{ 
     174#divbody #rightside h1{ 
    175175font-size:1.4em; 
    176176font-weight:400; 
     
    178178} 
    179179 
    180 #rightside p{ 
     180#divbody #rightside p{ 
    181181font-size:0.9em; 
    182182margin:2px 0 12px 10px; 
    183183} 
    184184 
    185 #rightside img{ 
     185#divbody #rightside img{ 
    186186border:1px solid #fa9035; 
    187187margin:10px 0 5px 5px; 
     
    189189} 
    190190 
    191 #content{ 
     191#divbody #content{ 
    192192margin:45px 160px 0 180px; 
    193193} 
    194194 
    195 #contentalt{ 
     195#divbody #contentalt{ 
    196196margin:45px 15px 0 180px; 
    197197} 
     
    199199#content p,#contentalt p{ 
    200200margin:8px 0 0 10px; 
     201color:#505050 ! important; 
     202font:76% Georgia,Verdana,Tahoma,Arial,sans-serif ! important; 
    201203} 
    202204 
     
    207209margin:15px 0 10px; 
    208210padding:0; 
     211color:#505050 ! important; 
     212font: Georgia,Verdana,Tahoma,Arial,sans-serif ! important; 
    209213} 
    210214 
     
    215219margin:20px 0 10px; 
    216220padding:0; 
    217 
    218  
    219 #content img,#contentalt img{ 
     221color:#505050 ! important; 
     222font: Georgia,Verdana,Tahoma,Arial,sans-serif ! important; 
     223
     224 
     225#divbody #content img,#divbody #contentalt img{ 
    220226border:1px solid #fa9035; 
    221227float:left; 
     
    223229} 
    224230 
    225 #footer{ 
     231#divbody #footer{ 
    226232clear:both; 
    227233color:#a0a0a0; 
     
    234240} 
    235241 
    236 #footer a{ 
     242#divbody #footer a{ 
    237243color:#a0a0a0; 
    238244font-weight:400; 
    239245} 
    240246 
    241 #footer a:hover{ 
     247#divbody #footer a:hover{ 
    242248color:#a0a0a0; 
    243249text-decoration:underline; 
    244250} 
    245251 
    246 .menublock{ 
     252#divbody .menublock{ 
    247253margin-bottom:10px; 
    248254} 
    249255 
    250 .nav{ 
     256#divbody .nav{ 
    251257color:#d04a10; 
    252258display:block; 
     
    260266} 
    261267 
    262 .nav:hover{ 
     268#divbody .nav:hover{ 
    263269border:1px solid #fa9035; 
    264270color:#505050; 
     
    266272} 
    267273 
    268 .sub{ 
     274#divbody .sub{ 
    269275font-size:0.9em; 
    270276margin-left:20px; 
     
    273279} 
    274280 
    275 .sub:hover{ 
     281#divbody .sub:hover{ 
    276282border:1px solid #fa9035; 
    277283color:#505050; 
     
    279285} 
    280286 
    281 .intro{ 
     287#divbody .intro{ 
    282288font-weight:700; 
    283289} 
    284290 
    285 .active{ 
     291#divbody .active{ 
    286292border:1px solid #fa9035; 
    287293padding:1px 1px 1px 9px; 
    288294} 
    289295 
    290 .box{ 
     296#divbody .box{ 
    291297background:#f8f8f8 url(../img/boxbg.gif) top left repeat-y; 
    292298border:1px solid #d0d4d4; 
     
    297303} 
    298304 
    299 .photo{ 
     305#divbody .photo{ 
    300306margin:5px auto 15px; 
    301307padding:5px; 
    302308} 
    303309 
    304 .smallcaps{ 
     310#divbody .smallcaps{ 
    305311font-variant:small-caps; 
    306312} 
    307313 
    308 .mini{ 
     314#divbody .mini{ 
    309315color:#a0a0a0; 
    310316font-size:0.75em; 
     
    314320} 
    315321 
    316 .small{ 
     322#divbody .small{ 
    317323font-size:0.85em; 
    318324} 
    319325 
    320 .large{ 
     326#divbody .large{ 
    321327font-size:1.4em; 
    322328} 
    323329 
    324 .soft{ 
     330#divbody .soft{ 
    325331color:#808080; 
    326332} 
    327333 
    328 .normal{ 
    329 font-weight:400; 
    330 } 
    331  
    332 .sharp{ 
     334#divbody .normal{ 
     335font-weight:400; 
     336} 
     337 
     338#divbody .sharp{ 
    333339color:#101010; 
    334340} 
    335341 
    336 .center{ 
     342#divbody .center{ 
    337343text-align:center; 
    338344} 
    339345 
    340 .hide{ 
     346#divbody .hide{ 
    341347display:none; 
    342348} 
  • tracistanplugin/0.10/example/aftracistan/aftracistan/status.py

    r697 r711  
    66import os.path 
    77from pkg_resources import resource_filename 
    8 from tracistan import IStanRequestHandler 
     8from tracistan import IStanRequestHandler, IStanRenderer 
     9from nevow import tags as T 
    910 
    1011__all__ = ['StatusPage'] 
     
    1819 
    1920    def match_request(self, req): 
    20         self.log.info(str(req.args)) 
    21         return req.path_info == '/status' 
     21        return req.path_info == '/aftracistan' 
    2222 
    2323    def process_request(self, req): 
     
    2525        req.standata.update({ 'name': 'Pacopablo', 
    2626                 'message' : 'Hello vatos!', 
    27                  'title' : 'Pyrus', 
     27                 'title' : 'Aftracistan', 
     28                 'tidy'  : True, 
     29                 'nav' : [{ 'link_name' : 'Front page', 
     30                            'link_id'   : 'current', 
     31                            'link_url'  : 'index.html', }, 
     32                          { 'link_name' : 'Alternative layout', 
     33                            'link_id'   : None, 
     34                            'link_url'  : 'alternative.html', }, 
     35                          { 'link_name' : 'Photo layout', 
     36                            'link_id'   : None, 
     37                            'link_url'  : 'photos.html', }, 
     38                          { 'link_name' : 'Styles', 
     39                            'link_id'   : None, 
     40                            'link_url'  : 'styles.html', }, 
     41                          { 'link_name' : 'Empty', 
     42                            'link_id'   : None, 
     43                            'link_url'  : 'empty.html', }, 
     44                         ] 
    2845               }) 
    2946        return ('index.stan', None) 
     
    5168 
    5269 
     70class StatusRenderers(Component): 
     71    implements(IStanRenderer) 
     72 
     73    def get_renderers(self): 
     74        """Map methods to method names""" 
     75        return { 
     76                'render_nav_row' : self._render_nav_row, 
     77               } 
     78 
     79    def _render_nav_row(self, context, data): 
     80        return context.tag(id=data['link_id'])[T.a (href=data['link_url']) [ data['link_name'] ]] 
  • tracistanplugin/0.10/example/aftracistan/aftracistan/templates/index.stan

    r696 r711  
    11inherits (template='tracmain.stan') [ 
    22    override (slot='pagebody') [ 
     3    div (id="divbody" ) [ 
    34        div (id="container") [  
    45            a (id="top"), 
     
    1718            ], 
    1819            div (id="nav") [ 
    19                 ul [ 
    20                     li (id="current") [ 
    21                         a (href="index.html") [ 'Front page' ] 
    22                     ], 
    23                     li [ 
    24                         a (href="alternative.html") [ 'Alternative layout' ] 
    25                     ], 
    26                     li [ 
    27                         a (href="photo.html") [ 'Photo layout' ] 
    28                     ], 
    29                     li [ 
    30                         a (href="styles.html") [ 'Styles' ] 
    31                     ], 
    32                     li [ 
    33                         a (href="empty.html") [ 'Empty' ] 
    34                     ], 
     20                ul (render=render.sequence, data=vars.nav) [ 
     21                    li (pattern='item', render=render_nav_row) 
    3522                ], 
    3623                p (_class="hide") [ 
     
    10390                    div (id="content") [ 
    10491                        h1 [ 'Welcome to "falling leaves"...' ], 
    105                         img (src="chrome/pyrus/img/gravatar-leaf.jpg", height="80", 
     92                        img (src="chrome/aftracistan/img/gravatar-leaf.jpg", height="80", 
    10693                             width="80", alt="Gravatar example"), 
    10794                        p (_class="intro") [ '...also known as "andreas06", yet another open source ' 
     
    138125        ] 
    139126    ] 
     127    ] 
    140128] 
  • tracistanplugin/0.10/stan/stansupport.py

    r697 r711  
    9595 
    9696    def _inherits_tag (self, template, locals, globals): 
    97         self.log.debug("called _inherits_tag") 
    9897        filename = self.find_template(template) 
    99         self.__superTemplate = eval(file(filename, 'rU' ).read(),  
     98        self.__superTemplate = eval(file(filename, 'rU').read(),  
    10099                                    locals, globals) 
    101100        return T.invisible 
    102101 
    103102    def _replace_tag (self, slot): 
    104         self.log.debug("called _replace_tag") 
    105         self.log.debug("slot: %s" % str(slot)) 
    106          
    107103        return T.invisible(slot=slot) 
    108104 
    109105    def _include_tag (self, template, locals, globals): 
    110         self.log.debug("called _include_tag") 
    111106        try: 
    112107            filename = self.find_template(template) 
     
    146141        filename = self.find_template(template) 
    147142 
     143        pretty = False 
     144        if info.has_key('tidy'): 
     145            pretty = info['tidy'] 
     146 
    148147        ns = {} 
    149148 
    150         if format.startswith('tidy.'): 
    151             pretty, format = format.split('.') 
    152         else: 
    153             pretty = False 
    154149        if format == 'html': 
    155150            ns.update(__import__('nevow.tags', ns, ns, ['__all__']).__dict__) 
     
    189184                           for c in self.__template.children]) 
    190185             
    191             from pprint import PrettyPrinter 
    192             ppstream = StringIO()  
    193             pp = PrettyPrinter(stream=ppstream) 
    194             pp.pprint(parts) 
    195             self.log.debug("parts: %s" % ppstream.getvalue()) 
    196186            for slot, fragment in parts.items(): 
    197187                self.__superTemplate.fillSlots(slot, fragment) 
    198             from pprint import PrettyPrinter 
    199             ppstream = StringIO()  
    200             pp = PrettyPrinter(stream=ppstream) 
    201             pp.pprint(self.__superTemplate) 
    202             self.log.debug("__superTemplate: %s" % ppstream.getvalue()) 
    203188            output = flatten(self.__superTemplate) 
    204189        else: 
     
    221206    def get_renderers(self): 
    222207        """Map methods to method names""" 
    223         self.log.debug("called get_renderers") 
    224         return {'tracPageTitle' : self._pageTitle, 
    225                 'tracNoRobots' : self._robots, 
    226                 'tracLinks' : self._links, 
    227                 'tracScript' : self._scripts, 
    228                 'tracProjectLogo' : self._project_logo, 
     208        return { 
    229209                'includeCS' : self._include_cs, 
    230210               } 
    231211 
    232     def _pageTitle(self, context, data): 
    233         self.log.debug("called _pageTitle") 
    234         self.log.debug("data: %s" % str(type(data))) 
    235         if data.project.name_encoded: 
    236             t = [data.title or '', 
    237                  ' - ', 
    238                  data.project.name_encoded, 
    239                  ' - Trac',] 
    240         else: 
    241             t = ['Trac: ', 
    242                  data.project.name_encoded,] 
    243         return context.tag[''.join(t)] 
    244  
    245     def _robots(self, context, data): 
    246         self.log.debug("called _robots") 
    247         if data.html.norobots: 
    248             return context.tag(name="ROBOTS", content="NOINDEX, NOFOLLOW") 
    249  
    250     def _links(self, context, data): 
    251         self.log.debug("called _links") 
    252         return '' 
    253  
    254     def _scripts(self, context, data): 
    255         self.log.debug("called _scripts") 
    256         return '' 
    257  
    258212    def _include_cs(self, context, data): 
    259         self.log.debug("called _include_cs") 
    260         return '<!-- THis is cs stuff -->' 
    261  
    262     def _project_logo(self, context, data): 
    263         self.log.debug("called _project_logo") 
    264         href = data.chrome.logo.link 
    265         logosrc = data.chrome.logo.src 
    266         logowidth = data.chrome.logo.width 
    267         logoheight = data.chrome.logo.height 
    268         logoalt = data.chome.logo.alt 
    269         if logosrc: 
    270             image = T.img(src=logosrc, width=logowidth, height=logoheight,  
    271                           alt=logoalt) 
    272             print 'logosrc present: %s' % str(image) 
    273             return context.tag [T.a(id="logo", href=href)[image], T.hr] 
    274         else: 
    275             image = data.project.name_encoded 
    276             if image: 
    277                 return context.tag[T.h1 [ T.a(id="logo", href=href)[image] ]] 
    278         return "" 
     213        hdf = data['hdf'] 
     214        template = data['template'] 
     215        return T.xml(hdf.render(template)) 
     216 
    279217         
    280218class TracIStan(Component): 
     
    292230     
    293231    """ 
    294 #    abstract = True 
    295232    implements(IRequestHandler, ITemplateProvider) 
    296233    stanreqhandlers = ExtensionPoint(IStanRequestHandler) 
     
    301238    # IRequestHandler methods 
    302239    def match_request(self, req): 
    303         self.log.debug('IStanRequestHandlers:') 
    304         [self.log.debug('  Stan Request Handler   : %s' % type(x).__name__) 
    305              for x in self.stanreqhandlers] 
    306240        for handler in self.stanreqhandlers: 
    307241            if handler.match_request(req): 
     
    319253        hdf = getattr(req, 'hdf', None) 
    320254        if hdf: 
    321             req.standata.update(self._convert_hdf_to_data(hdf)) 
     255            req.standata['hdf'] = hdf 
    322256        template, content_type = chosen_handler.process_request(req) 
    323257        content_type = content_type or 'text/html' 
     
    340274            outstream.close() 
    341275        else: 
     276            ct = content_type.split('/')[0] 
    342277            data = self._render(req.standata, template) 
    343278          
     
    358293        return self.stantheman.render(data, template=template) 
    359294 
    360     def _convert_hdf_to_data(self, hdf): 
    361         """Converts an HDFWrapper to a dictionary 
    362  
    363         """ 
    364         def reformat_data(data): 
    365             """Check to see if the keys are sequential numbers and reformats  
    366                into a list 
    367  
    368             """ 
    369             try: 
    370                 keys = [int(k) for k in data.keys()] 
    371                 keys.sort() 
    372                 datalist = [data[str(k)] for k in keys] 
    373                 return datalist 
    374             except ValueError: 
    375                 return data 
    376  
    377         def hdf_tree_walk(node): 
    378             d = {} 
    379             while node: 
    380                 name = node.name() or '' 
    381                 value = node.value() 
    382                 if (value or not node.child()) and name: 
    383                     d[name] = value.strip() 
    384                 if node.child() and name: 
    385                     data = hdf_tree_walk(node.child()) 
    386                     data = reformat_data(data) 
    387                     if data: 
    388                         d[name] = data 
    389                 node = node.next() 
    390             return d 
    391  
    392         return hdf_tree_walk(hdf.hdf.child()) 
    393  
    394295    # ITemplateProvider 
    395296    def get_templates_dirs(self): 
     
    412313 
    413314        """ 
    414 #        return [('blog', resource_filename(__name__, 'htdocs'))] 
    415315        return [] 
    416316 
  • tracistanplugin/0.10/stan/templates/tracmain.stan

    r696 r711  
    1 html [ 
    2     include(template='tracheader.stan'), 
    3     body [ 
    4         include(template='tracnav.stan'), 
    5 #        slot('pagebody'), 
    6         include(template='tracfooter.stan'), 
    7     ] 
     1invisible [ 
     2    invisible(render=includeCS, data={'hdf':vars.hdf, 'template':"header.cs"}), 
     3    slot('pagebody'), 
     4    invisible(render=includeCS, data={'hdf':vars.hdf, 'template':"footer.cs"}), 
    85]