[Grok-dev] Re: Relative filesystem path?

Philipp von Weitershausen philipp at weitershausen.de
Sun Sep 16 15:42:36 EDT 2007


On 16 Sep 2007, at 21:09 , Jim Washington wrote:
> Philipp von Weitershausen wrote:
>>
>> By the way, I'd spell that
>>
>>   loc = os.getcwd()
>>
> Thanks!  It's always good to catch a new trick.

The docs to the 'os' package would have taught you right away. I'm  
surprised where you caught that esoteric os.curdir trick :).

>>> Is there a good alternative?  Does grok have a hook I can use for  
>>> this
>>> that would not be so susceptible to breakage?  I've looked, but  
>>> it seems
>>> that the path I need is consumed and made unimportant by martian.
>>
>> I hope I'm understanding you right. I assume you want to be able to
>> refer to files in a package. So your relative filenames are relative
>> to package (much like app_templates, for example, is relative to the
>> package that app.py is in).
>>
>> The canonical way to do that is to use __file__. For example, let's
>> say I'm in foo.py and wanted to read xyz.txt which is next to foo.py:
>>
>>   foo_directory = os.path.dirname(__file__)
>>   xyz_txt = os.path.join(foo_directory, 'xyz.txt')
>>
> Actually, I want the place where the application is, not the library
> location, which is why I was using the cwd stuff.  I'm thinking  
> that an
> application should be able to do
>
> class Index(mylibrary.LXMLEnabledDescendentOfGrok.View):
>     template='base.html'
>     def render(self):
>         nav = self.body.get_element_by_id('navigation')
>         for k in navItems:
>             li = SubElement(nav,'li',{'class':'navitem'})
>             a = SubElement(li,'a',{'href':k.href})
>             a.text = k.title
>     ...
>
> where base.html has a div element with an id of 'navigation' and  
> resides
> in the 'html' directory which is in the same folder as the  
> app_templates
> folder.
>
> __file__ would just get me to the files in my library package.  I want
> to put the html templates out where the web application is, not inside
> the library egg.

Yup, I understand. Here's what you can do:

   class Index(...):
       template = awesomelib.Template('base.html', __file__)

       def render(self):
           ...

Template() would be an actual object which could provide access to  
the template file at the same time. That way the path magic is  
confined to one component. (This is analogous to ViewPageTemplate  
objects on Zope 3 browser views).

You can go even further and adopt a scheme we have in Zope 3:

   class Index(...):
       template = awesomelib.Template('base.html')

       def render(self):
           ...

Hows does Template know about __file__ now? It walks back to the  
frame that's calling it and fetches it:

   class Template(object):

       def __init__(self, filename, base=None):
           if base is None:
               sys._getframe(1).f_globals['__file__']
           base = os.path.dirname(base)

If you look at typical Zope 3 view code, we use the same trick there:

   class Index(zope.publisher.browser.BrowserPage):

       __call__ = ViewPageTemplateFile('index.pt')



More information about the Grok-dev mailing list