python - Google App Engine: Correctly configuring a static site with advanced routing -
i've spent several shameful hours trying solve no avail...
problem:
i have static website developing 100% pre-processed via grunt & assemble (if familiar jekyll, same concept). has simple static blog component houses category directories of various names. such, need catch-all in app.yaml route them appropriately.
however, also have custom error page show in place of standard gae page status.
it seems cannot accomplish accounting both scenarios in app.yaml alone because can use catch-all target once.
here logic in current app.yaml
- url: (.*)/ static_files: dist\1/index.html upload: dist/index.html expiration: "15m" - url: /(.*) static_files: dist/\1/index.html upload: dist/(.*)/index.html expiration: "15m"
this perfect use case because routes path index file if exists in current directory. however, because uses catch-all, cannot again use following
- url: /(.*) static_files: custom_error.html
or depend on
error_handlers: - file: custom_error.html
because renders paths no matching url pattern...
ideas:
my next thoughts may able accomplish advanced routing via external python script
- url: /.* script: main.app
but after trying myriad of various setups have yet stumble onto way accomplish this.
one example of trail of breadcrumbs on be
import os import webapp2 import jinja2 # vars jinja_environment = jinja2.environment(loader=jinja2.filesystemloader('jinja'), extensions=['jinja2.ext.autoescape'], autoescape=true) class mainhandler(webapp2.requesthandler): def get(self): if (an-index-file-exists-in-this-directory) # follow same static file logic app.yaml # static_files: dist/\1/index.html # upload: dist/(.*)/index.html else: template = jinja_environment.get_template('404/index.html') context = { 'page_title': '404', } self.response.out.write(template.render(context)) self.error(404) app = webapp2.wsgiapplication([ ('/.*', mainhandler) ], debug=false)
i'm not sure if taking external python file solve issue or not, awkward stab @ it.
does have ideas on how can achieve custom error pages when catch-all pattern being used important purpose?
update: solved
ok have figured out, because stack overflow thinks i'm not cool enough answer own question (low point threshold?), i've posted solution here:
https://gist.github.com/dustintheweb/c5e6e4ee1a64d50d7f87
good luck!
as @anthuin's answer points out, can't write (nor modify) index.html
files on disk (nor create new ones dynamically), makes little sense try read them disk -- "disk" available gae apps read-only (and split between part available static serving, , part readable app code itself).
rather, unless index.html
files huge (unlikely, suspect), i'd keep them in gae datastore app. simple model:
from google.appengine.ext import ndb class indx(ndb.model): body = ndb.textproperty()
assuming path no longer 500 characters , body megabyte. then, mainhandler
becomes pretty simple:
class mainhandler(webapp2.requesthandler): def get(self): key = ndb.key('indx', self.request.path) ent = key.get() if ent: self.response.write(ent.body) else: # existing 404-returning code goes here
the app.yaml
routing /.*
script, , app =
code, need no change.
now, thing remains is, how did expect write, or modify, these index.html
files (now datastore entities)? have no idea because long were files app couldn't possibly have written nor modified them. in case, they're in data store, writing becomes simple:
def write_indx(path, body): ent = indx(body=body, id=path) ent.put()
note there no real "modify" -- possibly "modify" index.html
's "body", you'll read previous one, make new body
string, , rewrite entity above write_indx
.
potential problems include: bodies of more 1 mb; and, keys (paths) of more 500 characters. former can worked around using, @anhuin suggested, google cloud storage instead of gae datastore; latter may perhaps problem because gcs object names have limits (differently gcs object lengths) -- specifically, 1024 bytes once name converted utf-8. either of these issues problem you? if so, let know!
Comments
Post a Comment