Creates a handler for `url` for servering combined js/css for `prefix/*` pages
(url, prefix)
| 183 | |
| 184 | |
| 185 | def create_dynamic_document(url, prefix): |
| 186 | """Creates a handler for `url` for servering combined js/css for `prefix/*` pages""" |
| 187 | doc = DynamicDocument(prefix) |
| 188 | |
| 189 | if url.endswith(".js"): |
| 190 | content_type = "text/javascript" |
| 191 | elif url.endswith(".css"): |
| 192 | content_type = "text/css" |
| 193 | else: |
| 194 | content_type = "text/plain" |
| 195 | |
| 196 | class page(delegate.page): |
| 197 | """Handler for serving the combined content.""" |
| 198 | |
| 199 | path = "__registered_later_without_using_this__" |
| 200 | |
| 201 | def GET(self): |
| 202 | i = web.input(v=None) |
| 203 | v = doc.md5() |
| 204 | if v != i.v: |
| 205 | raise web.seeother(web.changequery(v=v)) |
| 206 | |
| 207 | if web.modified(etag=v): |
| 208 | oneyear = 365 * 24 * 3600 |
| 209 | web.header("Content-Type", content_type) |
| 210 | web.header("Cache-Control", "Public, max-age=%d" % oneyear) |
| 211 | web.lastmodified(doc.last_modified) |
| 212 | web.expires(oneyear) |
| 213 | return delegate.RawText(doc.get_text()) |
| 214 | |
| 215 | def url(self): |
| 216 | return url + "?v=" + doc.md5() |
| 217 | |
| 218 | def reload(self): |
| 219 | doc.update() |
| 220 | |
| 221 | class hook(client.hook): |
| 222 | """Hook to update the DynamicDocument when any of the source pages is updated.""" |
| 223 | |
| 224 | def on_new_version(self, page): |
| 225 | if page.key.startswith(doc.root): |
| 226 | doc.update() |
| 227 | |
| 228 | # register the special page |
| 229 | delegate.pages[url] = {} |
| 230 | delegate.pages[url][None] = page |
| 231 | return page |
| 232 | |
| 233 | |
| 234 | all_js = create_dynamic_document("/js/all.js", config.get("js_root", "/js")) |