site.media_url when media is not an absolute path

64 views
Skip to first unread message

Steven Bethard

unread,
Oct 12, 2011, 8:35:28 AM10/12/11
to hyde...@googlegroups.com
Hi everyone. I'm updating an old rest2web site to use Hyde instead. So far, things have been pretty smooth, but I'm stuck on one problem:

I have in my base.j2 something like:

  <link rel="stylesheet" href="{{ site.media_url('css/style.css') }}">

And my directory structure looks something like:

  + content
    + media
      + css
        - style.css
    - index.html
    - foo.html
    + bar
      - baz.html

For index.html and foo.html, the <link/> works fine - it becomes "media/css/style.css". However, it also becomes "media/css/style.css" for baz.html, while it will only actually find the media files if it uses "../media/css/style.css".

I imagine this would not be a problem if the media url were "/media" instead of "media", but unfortunately, my site will be hosted in a subdirectory of another larger site, so "/media" won't be the right place - I really do need the path to the media directory, relative to the current resource.

So how can I get the appropriate number of ".." folders in my media_url path?

Grygoriy Fuchedzhy

unread,
Oct 12, 2011, 8:49:09 AM10/12/11
to hyde...@googlegroups.com

I think you can set
media_url: /path/to/your/site/subfolder/media
in your site.yaml and it will generate correct absolute path

By the way, you don't need to call media_url as method of site object. Just call
it this way {{media_url('some_url')}}. This is shorter to write, and this will
probably change in future, media_url wouldn't be a method of site object.

--
Grygoriy Fuchedzhy

Steven Bethard

unread,
Oct 12, 2011, 9:07:43 AM10/12/11
to hyde...@googlegroups.com
If I set the media_url in site.yaml, then I'll need to be editing that all the time - I'll have to set it to one path to check the Hyde output in the local "deploy" folder, and I'll have to set it to another path when I actually publish the webpages to the real site. This is why I was hoping for a ".." based solution.

Thanks for the note about site.media_url. I'll fix that in my code.

Vincent Bernat

unread,
Oct 12, 2011, 9:11:00 AM10/12/11
to hyde...@googlegroups.com

For this, I use two configuration file: one for development and another
one for production (the later extends the former).

Steven Bethard

unread,
Oct 12, 2011, 9:27:49 AM10/12/11
to hyde...@googlegroups.com
I guess I can go that route. It just seems like extra effort that shouldn't be necessary since the relative location of the media files doesn't change at all. (I totally understand wanting multiple configuration files when the relative locations of files really do change, e.g. when media is hosted somewhere else.)

If Jinja allowed me to write full Python code, I could do something like:

n_parents = len(resource.relative_path.split('/') - 1
'/'.join(".." for _ in range(n_parents)) + '/' + media_url('css/style.css')

Steven Bethard

unread,
Oct 12, 2011, 9:36:01 AM10/12/11
to hyde...@googlegroups.com
Turns out that I can do it like this:

    '/'.join(resource.relative_path.count('/') * ['..'] + [media_url('css/style.css')])

Which isn't pretty, but it works. I discovered that I also have to do this for things like the items in the menu:

    {% for menu_item in menu -%}
        <a href="{{ '/'.join(resource.relative_path.count('/') * ['..'] + [menu_item.url]) }}">{{ menu_item.title }}</a>
    {%- endfor %}

I'd be happy to find a nicer way of doing this, but at least this will work for me for the moment.

Grygoriy Fuchedzhy

unread,
Oct 12, 2011, 9:57:47 AM10/12/11
to hyde...@googlegroups.com

integration branch of hyde supports plugins defined at your site, so you can do
something like this:

add to plugins list in site.yaml
- plugins.CustomPlugin
then add plugins.py with something like this:
> from hyde.plugin import Plugin
> from hyde.site import Resource
>
> class CustomPlugin(Plugin):
> def begin_site(self):
> def media_url(self, path):
> return '/'.join(self.relative_path.count('/') * ['..'] + [self.site.media_url(path)])
> Resource.media_url = media_url

After this you can call {{resource.media_url("some_url")}} which is clearer.

P.S. Didn't test this code, but I think you've got an idea.

By the way, this is one more example, when media_url should got more context
then just site object.

--
Grygoriy Fuchedzhy

Steven Bethard

unread,
Oct 12, 2011, 10:04:46 AM10/12/11
to hyde...@googlegroups.com
Cool, this is the kind of thing I was looking for. Thanks!
Reply all
Reply to author
Forward
0 new messages