Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Display all jinja object attributes

Is there a way to display the name/content/functions of all attributes of a given object in a jinja template. This would make it easier to debug a template that is not acting as expected.

I am building a website using the hyde framework and this would come in quite handy since I am still learning the intricacies of both jinja and hyde.

Originally, I had thought it would work to use the attr filter, but this seems to require a name value. I would like to to not have to specify the name in order to get all available attributes for the object.

Some google searching showed django syntax looks like the following, but I am not familiar with django so this may only apply to database items. Long story short, I would like a method that works kind of like this for any object named obj

{% for field, value in obj.get_fields %}
    {{ field }} : {{ value }} </br>
{% endfor %}

final solution:

@jayven was right, I could create my own jinja2 filter. Unfortunately, using the stable version of hyde (0.8.4), this is not a trivial act of having a filter in the pythonpath and setting a simple yaml value in the site.yaml file (There is a pull-request for that). That being said, I was able to figure it out! So the following is my final solution which ends up being very helpful for debugging any unkown attributes.

It's easy enough to create site-specific hyde extensions just create a local python package with the following directory tree

hyde_ext
    __init__.py
    custom_filters.py

Now create the extension:

from hyde.plugin import Plugin
from jinja2 import environmentfilter, Environment


debug_attr_fmt = '''name:  %s
type:  %r
value: %r'''

@environmentfilter
def debug_attr(env, value, verbose=False):
    '''
    A jinja2 filter that creates a <pre> block
    that lists all the attributes of a given object
    inlcuding the value of those attributes and type.

    This filter takes an optional variable "verbose",
    which prints underscore attributes if set to True.
    Verbose printing is off by default.
    '''

    begin = "<pre class='debug'>\n"
    end = "\n</pre>"

    result = ["{% filter escape %}"]
    for attr_name in dir(value):
        if not verbose and attr_name[0] == "_":
            continue
        a = getattr(value, attr_name)
        result.append(debug_attr_fmt % (attr_name, type(a), a))
    result.append("{% endfilter %} ")
    tmpl = Environment().from_string("\n\n".join(result))

    return begin + tmpl.render() + end

    #return "\n\n".join(result)

# list of custom-filters for jinja2
filters = {
        'debug_attr' : debug_attr
        }

class CustomFilterPlugin(Plugin):
    '''
    The curstom-filter plugin allows any
    filters added to the "filters" dictionary
    to be added to hyde
    '''
    def __init__(self, site):
        super(CustomFilterPlugin, self).__init__(site)

    def template_loaded(self,template):
        super(CustomFilterPlugin, self).template_loaded(template)
        self.template.env.filters.update(filters)

To let hyde know about the extension add hyde_ext.custom_filters.CustomFilterPlugin to the "plugins" list of the site.yaml file.

Lastly, test it out on a file, you can add this to some random page {{resource|debug_attr}} or the following to get even the underscore-attributes {{resource|debug_attr(verbose=True)}}

Of course, I should add, that it seems like this might become much easier in the future whenever hyde 1.0 is released. Especially since there is already a pull request waiting to implement a simpler solution. This was a great way to learn a little more about how to use jinja and hyde though!

like image 573
scicalculator Avatar asked Nov 18 '12 02:11

scicalculator


People also ask

What is the difference between Jinja and Jinja2?

In the past it was possible to generate templates from a string with the default environment configuration by using jinja. from_string . Jinja 2 provides a Template class that can be used to do the same, but with optional additional configuration.

What is jinja2templates?

Jinja. Jinja2 is a Python library that allows us to build expressive and extensible templates. It has special placeholders to serve dynamic data. A Jinja template file is a text file that does not have a particular extension.

What is Autoescape in Jinja2?

When autoescaping is enabled, Jinja2 will filter input strings to escape any HTML content submitted via template variables. Without escaping HTML input the application becomes vulnerable to Cross Site Scripting (XSS) attacks. Unfortunately, autoescaping is False by default.


1 Answers

I think you can implement a filter yourself, for example:

from jinja2 import *

def show_all_attrs(value):
    res = []
    for k in dir(value):
        res.append('%r %r\n' % (k, getattr(value, k)))
    return '\n'.join(res)

env = Environment()
env.filters['show_all_attrs'] = show_all_attrs

# using the filter
tmpl = env.from_string('''{{v|show_all_attrs}}''')
class Myobj(object):
    a = 1
    b = 2

print tmpl.render(v=Myobj())

Also see the doc for details: http://jinja.pocoo.org/docs/api/#custom-filters

like image 199
jayven Avatar answered Oct 20 '22 04:10

jayven