Reputation: 50970
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).
Upvotes: 4
Views: 6040
Reputation: 21
Following dict worked for me (same can be specified in the config files as well):
conf = {
'/':{'tools.staticdir.root':'/Users/Desktop/Automation/CherryPy/ExecReport/html_code'
},
'/images': {
'tools.staticdir.on': True,
'tools.staticdir.dir': 'images'},
'/css': {
'tools.staticdir.on': True,
'tools.staticdir.dir': 'css'}
}
cherrypy.quickstart(SampleApp(), '/', conf)
We can define root at directory once and then we can provide relative directories.
Upvotes: 0
Reputation: 4689
I tried for hours to get the "official" cherrypy method to work, always with a 404 result. But this solution from google groups worked like a charm, so I'm reposting it here, where more people will find it.
For whatever reason, cherrypy's internal wrapper doesn't work, but this will render any files in a given folder public.
class StaticServer(object):
"""For testing - serves static files out of a given root.
"""
def __init__(self, rootDir):
self.rootDir = rootDir
if not os.path.isabs(self.rootDir):
self.rootDir = os.path.abspath(rootDir)
@cherrypy.expose
def default(self, *args):
file = os.path.join(self.rootDir, *args)
return cherrypy.lib.static.serve_file(file)
Usage:
class Root(object):
static = StaticServer(r'./static')
Then if you put a file in your <root>/static
- it will work.
Source: https://groups.google.com/forum/#!topic/cherrypy-users/5h5Ysp8z67E
Upvotes: 0
Reputation: 14559
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"
Upvotes: 12
Reputation: 508
This works for me:
static_handler = cherrypy.tools.staticdir.handler(section="/", dir=settings.STATIC_ROOT)
cherrypy.tree.mount(static_handler, '/static')
or in your case:
css_handler = cherrypy.tools.staticdir.handler(section="/", dir='path/to/css')
cherrypy.tree.mount(css_handler, '/css')
Upvotes: 1