How to change paths to static assets in .css files?

202 views
Skip to first unread message

Thomi Richards

unread,
Jan 5, 2012, 4:24:21 PM1/5/12
to pylons-...@googlegroups.com
Hi,

I'm working on a pylons project, and we have users trying to host the web-app under a non-root path (i.e. host it at '/myapp/' rather than at '/'). We've been pretty good about using 'h.url_for' to generate links in our jinja2 templates, so most things work as expected. However, our CSS file has paths to icons, background images etc. Since these are served as static files these paths never get modified.

I'm sure this is a problem lots of people come across - can anyone suggest a solution? I can think of two possibilities:

1) Remove all paths from the css files, and put them in the jinja2 templates instead - this seems really ugly, and I'd rather not do this.
2) Somehow serve the css file as a jinja2 template. It'd be nice if there was some way to say ' all requests for a .css file should render the requested file with jinja2 and return the result.'

Any ideas?

Cheers,

--
Thomi Richards

Mike Orr

unread,
Jan 5, 2012, 5:47:54 PM1/5/12
to pylons-...@googlegroups.com
On Thu, Jan 5, 2012 at 1:24 PM, Thomi Richards <tho...@gmail.com> wrote:
> Hi,
>
> I'm working on a pylons project, and we have users trying to host the
> web-app under a non-root path (i.e. host it at '/myapp/' rather than at
> '/'). We've been pretty good about using 'h.url_for' to generate links in
> our jinja2 templates, so most things work as expected. However, our CSS file
> has paths to icons, background images etc. Since these are served as static
> files these paths never get modified.


If the CSS files have moving parts, they are templates, and should be
served that way. If Jinja2 can't render them, Mako can. You'll have
to set up a controller action for them, of course.

--
Mike Orr <slugg...@gmail.com>

Wyatt Baldwin

unread,
Jan 5, 2012, 8:35:43 PM1/5/12
to pylons-...@googlegroups.com

Can you just make the paths in your stylesheets relative?

Petr Blahos

unread,
Jan 6, 2012, 2:00:22 AM1/6/12
to pylons-...@googlegroups.com
>> I'm working on a pylons project, and we have users trying to host the
>> web-app under a non-root path (i.e. host it at '/myapp/' rather than at
>> '/'). We've been pretty good about using 'h.url_for' to generate links in
>> our jinja2 templates, so most things work as expected. However, our CSS file
>> has paths to icons, background images etc. Since these are served as static
[...]

>>
>> Any ideas?
>>
>
> Can you just make the paths in your stylesheets relative?

This works for me:
background: url(../img/logo.png);

while having project files
project/project/public/css/main.css
project/project/public/img/logo.png

--
Petr

Mattias

unread,
Jan 6, 2012, 3:32:57 AM1/6/12
to pylons-discuss
There are two things you can do without making your css files into
templates.

1. Always use relative paths in the css.
div.background {
background: url("../img/background.png")
}

Thats how I did it in the beginning. Unfortunately our css files keeps
moving around, during development they are split into several files
but during deployment most of them are merged into one file which
means the relative path is different during development and
production.

2. Use absolute paths and the base href attribute.
<html file> <base href="http://example.com/subpath/" />
<css file> div.background {
background: url("/static/img/background.png")
background: url("static/img/background.png")
}

This can sometimes cause other problems with relative paths like if
you have a page at "http://example.com/subpath/foo" and wanted to make
a link to "http://example.com/subpath/foo/bar". Ordinarily you could
just write <a href="bar">link to foo/bar</> but if you use the base
tag your link will go to "http://example.com/subpath/bar" instead.
request.route_url always generate the full link.

Jonathan Vanasco

unread,
Jan 6, 2012, 3:21:39 PM1/6/12
to pylons-discuss
I've preferred the relative and @base solutions before without much
issue.

i'm assuming you're talking about https://launchpad.net/sloecode/trunk

I would really focus on keeping the css out of the templating system.
your css/img/js files really should never touch a dynamic server in a
production environment and have a long long long caching expiry.

i guess the problem is that you need to support BOTH a placement at
root and on a subdirectory. that means you can't rewrite all the
routing so that it expects to be served in the subdir.

While you could rewrite the routing so requests for the css files are
handled by pylons instead of the static_files , I really don't like
that idea due to caching concerns.

looking at how you implemented http://bazaar.launchpad.net/~sloecode/sloecode/trunk/revision/141
, i would really suggest that you add a memory cache function to
this. rendering doesn't take much work, but there can be dozens of js/
css files.


i think the easiest way to handle it would be to use rewrite or proxy
rules to keep them on the top level. ie, your static files could be
in /_sloecode_css instead of /sloecode/_css . under pylons you would
have a folder _sloecode_css which would support dev and toplevel
work. if anyone wants to run it in a subdirectory, they can just
remap /_sloecode_css to serve out of /_sloecode/_css

ie:

Files:
/sloecode/_sloecode_css

Apache:
RewriteRule ^_sloecode_css/(.*)$ /sloecode/_sloecode_css/$1

it would be trivial to do on nginx or anything else too.

Thomi Richards

unread,
Jan 6, 2012, 4:40:41 PM1/6/12
to pylons-...@googlegroups.com
Hi,

On 7 January 2012 09:21, Jonathan Vanasco <jona...@findmeon.com> wrote:

looking at how you implemented http://bazaar.launchpad.net/~sloecode/sloecode/trunk/revision/141
, i would really suggest that you add a memory cache  function to
this.  rendering doesn't take much work, but there can be dozens of js/
css files.


Yeah, I think you may be right - I still need to do some performance tests, although we're really not worried about performance too much with sloecode.


Thanks everyone for the pointers - I at least have a solution that works, although with a bit more tweaking I think I can improve the situation.


Cheers,


--
Thomi Richards

Jonathan Vanasco

unread,
Jan 6, 2012, 5:31:49 PM1/6/12
to pylons-discuss
make sure to bench in terms of concurrency and try to send a long term
cache control header.

the problem i experienced years ago under similar setups (mod_perl and
mod_python) was this: the render/etc times were really nothing or the
items were served 'raw' by the app -- but all the js / css / img etc
items resulted in dozens of requests to the apps per page viewed.
because the apps had inherent overhead and would max out at , for
example , 20 concurrent requests instead of thousands like nginx could
easily handle, once person viewing a page could essentially lock up
the server for a 30-90 seconds. i believe this was one of the larger
issues affecting the performance of trac installs a while back as
well.

Craig Younkins

unread,
Jan 7, 2012, 11:28:46 AM1/7/12
to pylons-...@googlegroups.com
For our site we actually have a build process for our CSS templates at application start. This way we can have different domains depending on the configuration (testing, prod, dev), and it all works with the same templates. They are compiled at application start rather than being served dynamically because the context never changes and we can take advantage of nginx's speed at serving static content.

Craig Younkins




--
You received this message because you are subscribed to the Google Groups "pylons-discuss" group.
To post to this group, send email to pylons-...@googlegroups.com.
To unsubscribe from this group, send email to pylons-discus...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/pylons-discuss?hl=en.


Wyatt Baldwin

unread,
Jan 7, 2012, 1:14:57 PM1/7/12
to pylons-...@googlegroups.com
On Saturday, January 7, 2012 8:28:46 AM UTC-8, Craig Younkins wrote:
For our site we actually have a build process for our CSS templates at application start. This way we can have different domains depending on the configuration (testing, prod, dev), and it all works with the same templates. They are compiled at application start rather than being served dynamically because the context never changes and we can take advantage of nginx's speed at serving static content.

At work, I deploy several Pylons and Pyramid apps to various environments with different host names and application prefixes, and it seems to me that a build step such as this shouldn't be necessary. A combination of relative paths in CSS and appropriate static file configuration does the trick. I'm curious why this wouldn't work for your app. Can you share your code?

Craig Younkins

unread,
Jan 7, 2012, 7:31:05 PM1/7/12
to pylons-...@googlegroups.com
@Wyatt: The step may not be necessary for everyone. For us, we wanted the flexibility. We will be moving to a real template compiler like SASS in the very near future. No, I cannot share my code. To each his own.

Craig Younkins



--
You received this message because you are subscribed to the Google Groups "pylons-discuss" group.
To view this discussion on the web visit https://groups.google.com/d/msg/pylons-discuss/-/M9ZmPVP3_m0J.
Reply all
Reply to author
Forward
0 new messages