Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Serving css file from CherryPy

I'm having a devil of a time getting CherryPy to serve the necessary css file for the page returned.

My directory structure:

Application
     ab.py              (CherryPy application)
     ab.config          (CherryPy config file)
     html\              (html template folder)
        ab.html         (html template file)
     css\               (css folder)
         ab.css         (css file)

The link statement in ab.html:

  <link href="/css/ab.css" rel="stylesheet" type="text/css" />

And finally, ab.config

 [/]
 tools.staticdir.root = "/"

 [/css/ab.css]
 tools.staticfile.on = True
 tools.staticfile.filename = "/css/ab.css"

My template is loaded and rendered to the browser as I expected, but no styling is applied. If I change the template to use a relative address (../css/ab.css) and open the template as a file in the browser, the styling is applied.

It took me a while to get the configuration file to a point where CherryPy did not complain about bad paths when starting the application. At this point it starts, renders, and returns fine but simply doesn't appear to serve the css file to the browser.

Any help greatly appreciated.

Update based on kind suggestions from fumanchu:

Preferring to use staticdir, and now understanding that the root refers to the filesystem absolute path, I now have this in the config file:

 [/]
 tools.staticdir.root = "c:/users/myaccount/documents/clientname/application"

 [/css]
 tools.staticdir.on = True
 tools.staticdir.dir = "css"

In my HTML I have this style sheet link:

<link href="/css/ab.css" rel="stylesheet" type="text/css" />

And I'm starting CherryPy with this:

 cherrypy.quickstart(ABRoot(), '/', 'ab.config')

In this configuration, I still don't get styling on my web page. When I check the page source and click on the /css/ab.css link directly, I get

 NotFound: (404, "The path '/css/ab.css' was not found.")

(Note: I'm developing on a windows machine).

like image 740
Larry Lustig Avatar asked Dec 13 '22 09:12

Larry Lustig


1 Answers

Change it quickly! The static handlers take paths that are absolute to your filesystem. By setting tools.staticdir.root = "/" you are saying "serve any file from my hard drive".

Whew. Now that the panic is over, let's analyze in more detail. First of all, staticdir and staticfile are different tools, and don't interact (so you're only really at risk above if there's more config you're not showing us, like tools.staticdir.on = True). If you want to stick with staticfile, you need to provide tools.staticfile.root, not tools.staticdir.root. If you'd rather expose whole directories, then replace staticfile with staticdir throughout.

Second, let's fix that .root setting. It should be the path to your "Application" folder (that is, the folder that contains 'ab.py' etc).

Third, the staticdir and staticfile tools determine a disk path with a simple os.path.join(root, dir) (or root, filename), so if you're supplying a root, your .dir or .filename shouldn't start with a slash:

>>> import os
>>> os.path.join('/path/to/Application', '/css/ab.css')
'/css/ab.css'
>>> os.path.join('/path/to/Application', 'css/ab.css')
'/path/to/Application/css/ab.css'

Given all that, try this config:

[/]
tools.staticfile.root = "/path/to/Application"

[/css/ab.css]
tools.staticfile.on = True
tools.staticfile.filename = "css/ab.css"
like image 122
fumanchu Avatar answered Dec 14 '22 22:12

fumanchu