ninjadog.ext.pyramid — ninjadog 0.3.9 documentation

# Source code for ninjadog.ext.pyramid

    from pyramid_jinja2 import (
        Jinja2TemplateRenderer,
        TemplateNotFound,
        DottedNameResolver,
        parse_loader_options_from_settings,
        parse_env_options_from_settings,
        create_environment_from_options,
        IJinja2Environment,
        ENV_CONFIG_PHASE,
    )

    from ninjadog.ninjadog import render

    class PugTemplateRenderer(Jinja2TemplateRenderer):
        """
        Renders templates that have both pug and jinja2
        syntax.

        Conforms to `IRenderer <http://docs.pylonsproject.org/projects/pyramid/en/latest/api/interfaces.html#pyramid.interfaces.IRenderer>`_
        interface.
        """

        def __call__(self, value, system):
            try:
                system.update(value)
            except (TypeError, ValueError) as ex:
                raise ValueError('renderer was passed non-dictionary '
                                 'as value: %s' % str(ex))
            template = self.template_loader()
            return render(
                template.render(system),
                file=template.filename,
                context=system,
                with_jinja=True
            )

    class PugRendererFactory:
        """
        Renderer factory conforms to
        `IRendererFactory <http://docs.pylonsproject.org/projects/pyramid/en/latest/api/interfaces.html#pyramid.interfaces.IRendererFactory>`_
        interface.
        """
        environment = None

        def __call__(self, info):
            name, package = info.name, info.package

            def template_loader():
                # attempt to turn the name into a caller-relative asset spec
                if ':' not in name and package is not None:
                    try:
                        name_with_package = '%s:%s' % (package.__name__, name)
                        return self.environment.get_template(name_with_package)
                    except TemplateNotFound:
                        pass

                return self.environment.get_template(name)

            return PugTemplateRenderer(template_loader)

    def add_pug_renderer(config, name, settings_prefix='jinja2.', package=None):
        """
        This function is added as a method of a :term:`Configurator`, and
        should not be called directly.  Instead it should be called like so after
        ``pyramid_jinja2`` has been passed to ``config.include``:
        .. code-block:: python
           config.add_jinja2_renderer('.html', settings_prefix='jinja2.')
        It will register a new renderer, loaded from settings at the specified
        ``settings_prefix`` prefix. This renderer will be active for files using
        the specified extension ``name``.
        """
        renderer_factory = PugRendererFactory()
        config.add_renderer(name, renderer_factory)

        package = package or config.package
        resolver = DottedNameResolver(package=package)

        def register():
            registry = config.registry
            settings = config.get_settings()

            loader_opts = parse_loader_options_from_settings(
                settings,
                settings_prefix,
                resolver.maybe_resolve,
                package,
            )
            env_opts = parse_env_options_from_settings(
                settings,
                settings_prefix,
                resolver.maybe_resolve,
                package,
            )
            env = create_environment_from_options(env_opts, loader_opts)
            renderer_factory.environment = env

            registry.registerUtility(env, IJinja2Environment, name=name)

        config.action(
            ('pug-renderer', name), register, order=ENV_CONFIG_PHASE)

    def includeme(config):
        config.add_directive('add_pug_renderer', add_pug_renderer)
        config.add_pug_renderer('.pug')