def test_typical_usage_via_domain_implied_collection(self): td = Domain(DEFAULT_DIR, restricted=RESTRICTED, errors=ERRORS) name = 'template.html' t = td.get_template(name) self.failUnless(t.collection is td.get_collection()) self.failUnless(t.collection is td.collections[""]) self.failUnless(t is t.collection.get_template(name)) self.failUnless(t is t.collection.domain.get_template(name, collection=t.collection))
class SitePublisher(Publisher): configuration = dict( http_address=('', 8001), as_https_address=('localhost', 9001), https_address=('localhost', 10001), scgi_address=('localhost', 11001), ) def __init__(self, **kwargs): super(SitePublisher, self).__init__(**kwargs) self.set_domain() def set_domain(self): default_dir = abspath(join(dirname(__file__), 'evoque')) # create template domain instance # here restating all defaults, for doc convenience self.domain = Domain(default_dir, restricted=False, errors=3, log=logging.getLogger("evoque"), cache_size=0, auto_reload=60, slurpy_directives=True, quoting="xml", input_encoding="utf-8", filters=[]) # extensions to global namespace self.domain.set_on_globals("pformat", pformat) # preload a default template, e.g. for error pages self.domain.get_collection().get_template("", "base.html") # other setup e.g. adding other collections, template aliases # see: http://evoque.gizmojo.org/usage/ def page(self, title, *content, **kwargs): """(title, *content, **kwargs) -> qpy.xml Return a page formatted according to the site-standard. """ # we make use of only the "template" kwarg -- there are # other possibilities, see: domain.get_template() template = kwargs.get("template", "") return self.domain.get_template(template).evoque(title=title, content=content, **kwargs)
class SitePublisher(Publisher): configuration = dict( http_address=('', 8001), as_https_address=('localhost', 9001), https_address=('localhost', 10001), scgi_address=('localhost', 11001), ) def __init__(self, **kwargs): super(SitePublisher, self).__init__(**kwargs) self.set_domain() def set_domain(self): default_dir = abspath(join(dirname(__file__), 'evoque')) # create template domain instance # here restating all defaults, for doc convenience self.domain = Domain(default_dir, restricted=False, errors=3, log=logging.getLogger("evoque"), cache_size=0, auto_reload=60, slurpy_directives=True, quoting="xml", input_encoding="utf-8", filters=[] ) # extensions to global namespace self.domain.set_on_globals("pformat", pformat) # preload a default template, e.g. for error pages self.domain.get_collection().get_template("", "base.html") # other setup e.g. adding other collections, template aliases # see: http://evoque.gizmojo.org/usage/ def page(self, title, *content, **kwargs): """(title, *content, **kwargs) -> qpy.xml Return a page formatted according to the site-standard. """ # we make use of only the "template" kwarg -- there are # other possibilities, see: domain.get_template() template = kwargs.get("template", "") return self.domain.get_template(template).evoque( title=title, content=content, **kwargs)
def __init__(self, domain, name, src=None, collection=None, raw=None, data=None, from_string=False, # defaults from Collection quoting=None, input_encoding=None, filters=None): """ domain: either(str, Domain) abs path, or actual domain instance name: str if no src this is collection-root-relative locator src: either(None, str) (file-based) collection-root-relative locator (from_string=True) template source string collection: either(None, str, Collection) None implies default collection, else str/Collection refer to an existing collection raw: bool if raw, do not compile the template source data: either(None, dict) default data for template evaluation from_string: bool when True src must specify the template source For more on defaults from Collection init parameters, see the docstring in collection.Collection.__init__(). Preferred way to create a new template: domain.{get_template(), set_template()} """ # $end{init} # domain, ensure one is available if domain is None: raise ValueError("A Template cannot have a None domain") if isinstance(domain, string): # creates domain with the "" collection from evoque.domain import Domain domain = Domain(domain, **specified_kwargs(self.from_collection, vars())) # collection self.collection = domain.get_collection(collection) # name, qsclass, input_encoding, filters, raw, data if name is None: raise ValueError("A Template cannot have a None name") self.qsclass = get_qsclass(cascaded(quoting, self.collection.quoting)) self.input_encoding = cascaded(input_encoding, self.collection.input_encoding) self.filters = cascaded(filters, self.collection.filters) self.raw = raw or False self.data = data # src (stored as either .file or .ts_raw), file, label self.ts_raw = None self.last_modified = None if not name and src is None: raise ValueError("Template must specify a locator (name/src)") self.file, self.label = None, None if from_string: # src must hold the raw string self.label = parse_locator(name)[1] # from_string templates may only be loaded once self.ts_raw = self.redecode_from_string(src) self.last_modified = time.time() else: # name or src (or combination of both) must hold the locator if name: # fragment label from name takes precedence: # name, src = name#label, path/file.ext#label2 self.file, self.label = parse_locator(name) if src is not None: # file from src takes precedence self.file, label = parse_locator(src) if self.label is None: self.label = label if not exists(self.get_abspath()): raise ValueError("File [%s] not found for template " '[name="%s" collection="%s"]. Template File locator ' "(name/src) must be relative to collection root." % ( self.file, name, self.collection.name)) # never modify a user-specified name self.name = name # ts_raw + last_modified (file) self.eval_overlay, self.labels, self.prefer = None, None, None self.test_data, self.ts, self.ts_raw_frag = None, None, None self.refresh() if self.prefer: # may need to refresh still if different preferances than defaults refresh = (self.qsclass, self.raw) self.qsclass = get_qsclass(cascaded(quoting, self.prefer.get("quoting"), self.collection.quoting)) self.raw = cascaded(raw, self.prefer.get("raw"), self.raw) self.filters = cascaded(filters, self.prefer.get("filters"), self.collection.filters) if refresh != (self.qsclass, self.raw): self.refresh() try: self.collection.cache.get(name) raise ValueError(("A template named [%s] is already defined " "in collection [%s]") % (name, self.collection.name)) except KeyError: self.collection.cache.set(name, self) if not domain.restricted: self.evaluator = Evaluator(self) else: self.evaluator = RestrictedEvaluator(self)
def __init__( self, domain, name, src=None, collection=None, raw=None, data=None, from_string=False, # defaults from Collection quoting=None, input_encoding=None, filters=None): """ domain: either(str, Domain) abs path, or actual domain instance name: str if no src this is collection-root-relative locator src: either(None, str) (file-based) collection-root-relative locator (from_string=True) template source string collection: either(None, str, Collection) None implies default collection, else str/Collection refer to an existing collection raw: bool if raw, do not compile the template source data: either(None, dict) default data for template evaluation from_string: bool when True src must specify the template source For more on defaults from Collection init parameters, see the docstring in collection.Collection.__init__(). Preferred way to create a new template: domain.{get_template(), set_template()} """ # $end{init} # domain, ensure one is available if domain is None: raise ValueError("A Template cannot have a None domain") if isinstance(domain, string): # creates domain with the "" collection from evoque.domain import Domain domain = Domain(domain, **specified_kwargs(self.from_collection, vars())) # collection self.collection = domain.get_collection(collection) # name, qsclass, input_encoding, filters, raw, data if name is None: raise ValueError("A Template cannot have a None name") self.qsclass = get_qsclass(cascaded(quoting, self.collection.quoting)) self.input_encoding = cascaded(input_encoding, self.collection.input_encoding) self.filters = cascaded(filters, self.collection.filters) self.raw = raw or False self.data = data # src (stored as either .file or .ts_raw), file, label self.ts_raw = None self.last_modified = None if not name and src is None: raise ValueError("Template must specify a locator (name/src)") self.file, self.label = None, None if from_string: # src must hold the raw string self.label = parse_locator(name)[1] # from_string templates may only be loaded once self.ts_raw = self.redecode_from_string(src) self.last_modified = time.time() else: # name or src (or combination of both) must hold the locator if name: # fragment label from name takes precedence: # name, src = name#label, path/file.ext#label2 self.file, self.label = parse_locator(name) if src is not None: # file from src takes precedence self.file, label = parse_locator(src) if self.label is None: self.label = label if not exists(self.get_abspath()): raise ValueError( "File [%s] not found for template " '[name="%s" collection="%s"]. Template File locator ' "(name/src) must be relative to collection root." % (self.file, name, self.collection.name)) # never modify a user-specified name self.name = name # ts_raw + last_modified (file) self.eval_overlay, self.labels, self.prefer = None, None, None self.test_data, self.ts, self.ts_raw_frag = None, None, None self.refresh() if self.prefer: # may need to refresh still if different preferances than defaults refresh = (self.qsclass, self.raw) self.qsclass = get_qsclass( cascaded(quoting, self.prefer.get("quoting"), self.collection.quoting)) self.raw = cascaded(raw, self.prefer.get("raw"), self.raw) self.filters = cascaded(filters, self.prefer.get("filters"), self.collection.filters) if refresh != (self.qsclass, self.raw): self.refresh() try: self.collection.cache.get(name) raise ValueError( ("A template named [%s] is already defined " "in collection [%s]") % (name, self.collection.name)) except KeyError: self.collection.cache.set(name, self) if not domain.restricted: self.evaluator = Evaluator(self) else: self.evaluator = RestrictedEvaluator(self)
def load_environment(global_conf, app_conf): """Configure the Pylons environment via the ``pylons.config`` object """ # Pylons paths root = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) paths = dict(root=root, controllers=os.path.join(root, 'controllers'), static_files=os.path.join(root, 'public'), templates=[os.path.join(root, 'templates')]) # Initialize config with the basic options config.init_app(global_conf, app_conf, package='evoque_site', paths=paths) config['routes.map'] = make_map() config['pylons.app_globals'] = app_globals.Globals() config['pylons.h'] = evoque_site.lib.helpers # $begin{ext} ## # Evoque Templating: # http://evoque.gizmojo.org/ext/pylons/ # http://evoque.gizmojo.org/usage/api/ import logging from evoque.domain import Domain evoque_domain = Domain( # root folder for the default template collection, must be abspath; # as default use pylon's first templates folder os.path.join( root, app_conf.get("evoque.default_dir") or paths['templates'][0]), # whether evaluation namespace is restricted or not restricted=app_conf.get("evoque.restricted") == "true", # how should any evaluation errors be rendered # int 0 to 4, for: [silent, zero, name, render, raise] errors=int(app_conf.get("evoque.errors", 3)), # evoque logger; additional setings should be specified via the pylons # config ini file, just as for any other logger in a pylons application log=logging.getLogger("evoque"), # [collections] int, max loaded templates in a collection cache_size=int(app_conf.get("evoque.cache_size", 0)), # [collections] int, min seconds to wait between checks for # whether a template needs reloading auto_reload=int(app_conf.get("evoque.auto_reload", 60)), # [collections] bool, consume all whitespace trailing a directive slurpy_directives=app_conf.get("evoque.slurpy_directives") == "true", # [collections/templates] str or class, to specify the *escaped* # string class that should be used i.e. if any str input is not of # this type, then cast it to this type). # Builtin str key values are: "xml" -> qpy.xml, "str" -> unicode quoting=app_conf.get("evoque.quoting", "xml"), # [collections/templates] str, preferred encoding to be tried # first when decoding template source. Evoque decodes templates # strings heuristically, i.e. guesses the input encoding. input_encoding=app_conf.get("evoque.input_encoding", "utf-8"), # [collections/templates] list of filter functions, each having # the following signature: filter_func(s:basestring) -> basestring # The functions will be called, in a left-to-right order, after # template is rendered. NOTE: not settable from the conf ini. filters=[]) # default template (optional) i.e. what to receive # when calling domain.get_template() with no params if app_conf.get("evoque.default_template"): evoque_domain.get_collection().get_template( "", src=app_conf.get("evoque.default_template")) # attach evoque domain to app_globals config['pylons.app_globals'].evoque_domain = evoque_domain ## $end{ext} evoque_domain.log.debug(evoque_domain.__dict__)
def load_environment(global_conf, app_conf): """Configure the Pylons environment via the ``pylons.config`` object """ # Pylons paths root = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) paths = dict(root=root, controllers=os.path.join(root, 'controllers'), static_files=os.path.join(root, 'public'), templates=[os.path.join(root, 'templates')]) # Initialize config with the basic options config.init_app(global_conf, app_conf, package='evoque_site', paths=paths) config['routes.map'] = make_map() config['pylons.app_globals'] = app_globals.Globals() config['pylons.h'] = evoque_site.lib.helpers # $begin{ext} ## # Evoque Templating: # http://evoque.gizmojo.org/ext/pylons/ # http://evoque.gizmojo.org/usage/api/ import logging from evoque.domain import Domain evoque_domain = Domain( # root folder for the default template collection, must be abspath; # as default use pylon's first templates folder os.path.join(root, app_conf.get("evoque.default_dir") or paths['templates'][0]), # whether evaluation namespace is restricted or not restricted = app_conf.get("evoque.restricted")=="true", # how should any evaluation errors be rendered # int 0 to 4, for: [silent, zero, name, render, raise] errors = int(app_conf.get("evoque.errors", 3)), # evoque logger; additional setings should be specified via the pylons # config ini file, just as for any other logger in a pylons application log = logging.getLogger("evoque"), # [collections] int, max loaded templates in a collection cache_size = int(app_conf.get("evoque.cache_size", 0)), # [collections] int, min seconds to wait between checks for # whether a template needs reloading auto_reload = int(app_conf.get("evoque.auto_reload", 60)), # [collections] bool, consume all whitespace trailing a directive slurpy_directives = app_conf.get("evoque.slurpy_directives")=="true", # [collections/templates] str or class, to specify the *escaped* # string class that should be used i.e. if any str input is not of # this type, then cast it to this type). # Builtin str key values are: "xml" -> qpy.xml, "str" -> unicode quoting = app_conf.get("evoque.quoting", "xml"), # [collections/templates] str, preferred encoding to be tried # first when decoding template source. Evoque decodes templates # strings heuristically, i.e. guesses the input encoding. input_encoding = app_conf.get("evoque.input_encoding", "utf-8"), # [collections/templates] list of filter functions, each having # the following signature: filter_func(s:basestring) -> basestring # The functions will be called, in a left-to-right order, after # template is rendered. NOTE: not settable from the conf ini. filters=[] ) # default template (optional) i.e. what to receive # when calling domain.get_template() with no params if app_conf.get("evoque.default_template"): evoque_domain.get_collection().get_template("", src=app_conf.get("evoque.default_template")) # attach evoque domain to app_globals config['pylons.app_globals'].evoque_domain = evoque_domain ## $end{ext} evoque_domain.log.debug(evoque_domain.__dict__)