Sprox form with Turbogears, using Mako, only displays plain text - python

I'm generating a Sprox form with Turbogears 2.1 and trying to display it in a Mako template. Here is my code:
To define the form:
class NewUserForm(AddRecordForm):
__model__ = User
newuserform = NewUserForm(DBSession)
The controller definition that assigns the form and calls the template:
#expose('limelight.modules.users.templates.register')
def register(self, **kw):
tmpl_context.register_form = newuserform
return dict(value=kw)
And the relevant template code:
${tmpl_context.register_form(value=value)}
The problem is the HTML code is displayed as plain text on the page, not rendered HTML.

Figured it out. I have to pass the variable through the the 'n' mako filter to remove any automatic filters mako applies to the html generated. So:
${tmpl_context.register_form(value=value) | n}

Related

Loading Template in Admin Form for Custom Fields

I learned that I can add a custom button in my Admin form by adding it to
fields = ["connect"]
readonly_fields = ('connect',)
def connect(self, obj):
return format_html("<button></button>")
connect.allow_tags=True
connect.short_description = ''
However, the html I want to add to the connect is getting out of control. I was wondering if there's a proper (Django-nic) way to move that to a template and load and return the content of the template in the connect function.
I can think of reading the content of the template file (open('file.html', 'r')) to read the content, however, I am looking for a suggestion that aligns Django standards (if any).
P.S. I also tried creating a view for getting the HTML content of the connect file, but that for some reason doesn't seem to work and feels unnatural to do.
from django.template.loader import render_to_string
...
def connect(self, obj):
html = render_to_string('file.html')
return html
With file.html in templates directory

Update Jinja2 template variables

I am using appengine with Python and jinja2 template.
I encountered an issue during the process: I render a list of games with this code
self.templateValues = {}
self.templateValues['title'] = 'GalaStore'
self.templateValues['values'] = kw
gamesQuery = Game.all()
values = {'games' : gamesQuery.run()}
self.templateValues['gl'] = values
template = JINJA_ENVIRONMENT.get_template(template)
self.response.out.write(template.render(self.templateValues))
then I have some button-filters in my html, and everyone calls a different js function. The problem is: once I hit the filter "sort by alpha" and I call a python function "sortByAlpha" via js (via ajax), how can I update the template variables in runtime withouth calling the template.render() function again? That would cause the reloading of the entire page and I would like to avoid it.
Thank you very much!
Your AJAX request would either need to return the games object list in JSON form, so the JavaScript could update the list in the browser, or you would have a template rendering just that part of the page, and have JavaScript swap out that piece with the HTML loaded from your server.
The latter can be made reusable; have both your main view and your AJAX handler use the same template, rendering just the list of games (no the whole page):
def rendered_games_list(self, sort_by=None):
games_query = Game.all()
if sort_by:
# I winged this bit, you didn't specify the ORM used
games_query = games_query.order_by(sort_by)
template = JINJA_ENVIRONMENT.get_template(games_list_template)
return template.render(gl=games_query.run())
then use this part in your main view:
template_values = {
'title': 'GalaStore',
'values': kw,
'games_list': self.rendered_games_list()
}
template = JINJA_ENVIRONMENT.get_template(template)
self.response.out.write(template.render(self.templateValues))
and in your main template insert the rendered games list HTML as:
{{ games_list|safe }}
So your main template doesn't render the games list itself, it merely includes it.
Your AJAX handler can return the rendered_games_list() directly:
sort_order = self.request.get('sort_order', None)
self.response.out.write(self.rendered_games_list(sort_order))

How to show widgets on pages in Flask?

How can I create a widget on the site, such as login forms, dynamic menu (items taken from the database), site statistics?
I know that you can render a template that will extend out of a base template. And in the base template you can create these widgets.
But I do not know how to move the logic from the base template to my code. For example, the selection data for the block. Such actions certainly can be done in the template, but it would be a poor method in my opinion.
Sorry for my bad English. If you can not understand, I'll try to rephrase.
You would use a python library called WTForms. It helps you write code for creating forms and other widgets backed by database which you can render using jinja2 templates.
class YourForm(Form):
your_field1 = TextField()
....
your_fieldn = SubmitField()
#app.route('/')
def view():
form=YourForm()
return render_template('your.html', form=form)
In your.html
<form >
{{ form.your_field1 }}
....
{{ form.your_fieldn }}
</form>
Check out this flask pattern for form validation and rendering to know more about it.
Edit: To create global variables available to all templates,there are two ways:
You can use global dict of jinja environment.
This is the code:
app.jinja_env.globals.update({'variable':1})
You can use ContextProcessor. Code:
#app.context_processor
def inject_variable():
return dict(variable=1)
Now you can access variable in any template of your app.

Get template name in template tag ( Django )

is there a way to get the template name ( being parsed ) in a template tag ?
I have read searched and found nothing, only this previous post
Getting the template name in django template
which doesn't help me much, since the answer relies on settings.DEBUG being true, which in my case can't be.
I don't really know where to start on this one, so any suggestion is welcome :)
EDIT
So basically what i want is to create a plugable tag that when rendered it checks for a Tag object, this would be the source for the tag object
class Tag(models.Model):
template = models.CharFIeld(max_length=50)
name = models.CharField(max_length=100)
plugins = models.ForeignKey(PluginBase)
if theres a tag object, then it displays all plugin objects, if not it creates a tag object unique to the name provided in the template tag and the template name, if getting the template name is not possible, then i guess i can just make it unique per name. The whole tag is kinda like a placeholder, for those familiar with django-cms
You could perhaps do this with a context processor, but I'm not sure if these have access to the name of the template.
What will work is to make a wrapper for the rendering calls you do. Say you currently do the following:
from django.shortcuts import render
def index(request):
return render(request, 'app/index.html', { 'foo': 'bar', })
If you create your own wrapper for this, you could add the template name to the dictionary before the actual render takes place:
from django.shortcuts import render
def myrender(request, template, dictionary):
dictionary.update({'template_name': template})
return render(request, template, dictionary)
Then in your views, change it as follows (assuming you saved the above function in myutils.py, and it is available on your path):
#from django.shortcuts import render <- delete this line
from myutils import myrender as render
def index(request):
return render(request, 'app/index.html', { 'foo': 'bar', })
Now all your render calls will update the dictionary with the template name. In any template, then just use {{ template_name }} to get the name. You can of course also update other rendering function like render_to_response and such in a similar fashion.
Also, the import myrender as render might or might not confuse you later on because it is named like the Django function... if so, just import it without the "as render", and replace all render calls with myrender. Personally I'd prefer this since this makes it a drop-in replacement for the existing rendering functions.
Looking at the source, while the Template object would have access to the template name (via .name) this value is never passed on to the Parser object and therefore not available to template tags.
There are various ways of making the template name available to the template itself (by adding it to the context) but not within the template tags.
As Daniel Roseman mentioned in the comments, if you can elaborate on what you're actually trying to achieve, there may be a better way to achieve what you want. No offence, but this sounds like it may be an XY problem.
Out of academic interest, I had a quick fiddle to see if it was possible. As far as I can see, it is possible but not without changing or monkey patching the django source.
Note: the following is not a recommended solution and merely hints at what may be required to actually make this work. Not to be used for production code.
By modifying django.template.base.py with the following changes, we add the .template_name attribute to the parser object making it available to template tags.
Added optional arg to compile_string
Added template name as extra attribute to parser
Passed in the template name when calling compile_string()
To test this out, I defined the following tag which simply returns the template name in caps:
from django.template.base import Node, Library
register = Library()
class TemplateNameNode(Node):
def __init__(self, template_name):
self.name = template_name
def render(self, context):
return self.name.upper()
#register.tag
def caps_template_name(parser, token):
return TemplateNameNode(parser.template_name)
and the following template:
{% load mytags %}
Template name in caps: {% caps_template_name %}
This seems to work when tested in ./manage.py shell:
>>> from django.template import loader, Context
>>> t = loader.get_template("test.html")
>>> t.render(Context({}))
u'\nTemplate name in caps: TEST.HTML\n'
While this seems to work, I should reiterate that manually patching the django source never a good solution and is subject to all sorts of misery when migrating to different versions.

Pyramid - Is it possible to render my mako template as a string within my view callable?

I have a view callable that does looks similar to:
def post_comment(request):
""" Posts the users comment to the thread """
try:
new_comment = comments.post()
except InvalidComment as e:
return {'success' : False, 'message' : e.message}
# need to do something like:
new_comment = pyramid.template.render(new_comment)
return {'success' : True, 'message' : new_comment}
The route config for this view callable is:
config.add_route('post_comment',
'/comments/{link_id}/post',
view='site.views.post_comment',
view_renderer='json')
Using this, I can AJAXify my comment submissions and have a shiny web 2.0 website. The problem is, I'd like to render new_comment through my mako template to build the HTML and return that. However, I can't find a way to do this.
How can I render a mako template within my view callable to return the HTML as a JSON response?
You can call render directly using the documented Pyramid API here: http://docs.pylonsproject.org/projects/pyramid/1.0/api/renderers.html#pyramid.renderers.render
from pyramid.renderers import render
def my_view(request)
renderer_dict = {} # dictionary of values to pass to the renderer
new_comment = render('new_comment.mako', renderer_dict, request)
…
I'm not sure I understand your question but I think you need 2 views, one for json and another for the mako one. For the mako view follow the official docs and mmerickel's answer. If you want to have multiple view callables within the same class you can have a look to pyramid_handlers.

Categories