Invalid filter: 'markdown' django-markdown-deux - python

Before I explain my issue, let me tell you some basics of my system:
windows 10
python 3.6
django 1.9
I followed the documention of 'django-markdown-deux', from it, I learned it has four steps to be implemented.
Firstly: pip3 install django-markdown-deux
Secondly: add markdown_deux into your INSTALLED_APPS
Thirdly: add {% load markdown_deux_tags %} into your header.html
Finally: add {{ post.body|markdown }}, as I want to transfer post.body to markdown
{% extends "personal/header.html" %}
{% block content %}
<h3>{{ post.title }}</h3>
<h6> on {{ post.date }}</h6>
<div class = "container">
{{ post.body|markdown }}
</div>
<br><br>
{% endblock %}
after doing this, I have "Error during template rendering"
In template F:\django\mysite_1\blog\templates\blog\post.html, error at line 8
Invalid filter: 'markdown'

You need to load the tags in the template file which uses the tags (not in your header.html). In other words, you need to include {% load markdown_deux_tags %} in the same file as you call {{ post.body|markdown }}:
{% extends "personal/header.html" %}
{% load markdown_deux_tags %}
{% block content %}
<h3>{{ post.title }}</h3>
<h6> on {{ post.date }}</h6>
<div class = "container">
{{ post.body|markdown }}
</div>
<br><br>
{% endblock %}

Related

Flask Jinja 2 Rendering Issue

I am sure I am doing something wrong .
{% block content %}
<h1>Sign In</h1>
<form action="" method="post" novalidate>
{{ form.hidden_tag() }}
<p>
{{ form.username.label }}<br>
{{ form.username(size=32) }}
</p>
<p>
{{ form.password.label }}<br>
{{ form.password(size=32) }}
</p>
<p>{{ form.remember_me() }} {{ form.remember_me.label }}</p>
<p>{{ form.submit() }}</p>
</form>
{% endblock %}
{% extends "base.html" %}
Above code gives this output:
Which is correct. But when i change same code to as below :
{% extends "base.html" %}
{% block content %}
<h1>Sign In</h1>
<form action="" method="post" novalidate>
{{ form.hidden_tag() }}
<p>
{{ form.username.label }}<br>
{{ form.username(size=32) }}
</p>
<p>
{{ form.password.label }}<br>
{{ form.password(size=32) }}
</p>
<p>{{ form.remember_me() }} {{ form.remember_me.label }}</p>
<p>{{ form.submit() }}</p>
</form>
{% endblock %}
Output becomes like this:
My base.html looks like this:
<div>
Home
Login
</div>
I am sure , i am making some silly mistake but can not seem to find it .
if i copy the code from base.html on top of my code it renders correctly.
Hope someone can help.
You need to have a content block to override in your base.html
<div>
Home
Login
{% block content %}{%endblock%}
</div>
Your base.html should contain blocks in it for the various content blocks that you will have in your site.
When you create a new page and want to override that content or add content to those blocks you use extends like you have done.
{% extends "base.html" %}
{% block content %}
Your content goes here
{% endblock %}
You can have multiple blocks in your base.html and then override them when you want.
Jinja documentation
You can put content in the content blocks in your base html and then add to that content without overriding it using the super() function.
{% block content %}
{{ super() }}
New content here
{% endblock %}
The above can be handy for script files. If you have some that need to be site wide, and some only on specific pages.

Flask-security and Bootstrap

How can I style my Flask-security login site with Bootstrap? The html form looks like this:
<form action="{{ url_for_security('login') }}" method="POST" name="login_form">
{{ login_user_form.hidden_tag() }}
{{ render_field_with_errors(login_user_form.email) }}
{{ render_field_with_errors(login_user_form.password) }}
{{ render_field_with_errors(login_user_form.remember) }}
{{ render_field(login_user_form.next) }}
{{ render_field(login_user_form.submit) }}
</form>
Bootstrap is implemented, but I dont know how to edit the fields and the submit button..
The render_field_* functions accepts a class_ parameter, which will add HTML classes to the field. Add in bootstrap styling classes as you want.
render_field_with_errors(login_user_form.email, class_="form-control") }}
{{ render_field(login_user_form.submit, class_="btn btn-default") }}
And so on.
Flask-Security uses Flask-WTForms to render and validate forms. In Flask-Security 1.7.5, the default render_field_with_errors and render_field macros defined in "security/_macros.html" are
{% macro render_field_with_errors(field) %}
<p>
{{ field.label }} {{ field(**kwargs)|safe }}
{% if field.errors %}
<ul>
{% for error in field.errors %}
<li>{{ error }}</li>
{% endfor %}
</ul>
{% endif %}
</p>
{% endmacro %}
{% macro render_field(field) %}
<p>{{ field(**kwargs)|safe }}</p>
{% endmacro %}
According to the Flask-WTForms 0.10 docs, both of the above macro functions accept ...
... keyword arguments that are forwarded to WTForm’s field function that renders the field for us. The keyword arguments will be inserted as HTML attributes.
Specifically, the lines {{ field(**kwargs)|safe }} pass the HTML escaped keyword arguments to the field function. Therefore, you can add classes,
{{ render_field_with_errors(login_user_form.email, class="form-control") }}
and can also overwrite default HTML attributes,
{{ render_field_with_errors(login_user_form.email,
class="form-control", type="email", placeholder="Enter email") }}
{{ render_field(login_user_form.submit, class="btn btn-default", value="Submit" ) }}
Additionally, you can define your own macros by modifying the macros above. For example, if you wanted to use Bootstrap alerts to render form validation errors, you could define the macro function render_field_with_bootstrap_errors
{% macro render_field_with_bootstrap_errors(field) %}
<p>
{{ field.label }} {{ field(**kwargs)|safe }}
{% if field.errors %}
{% for error in field.errors %}
<div class="alert alert-danger" role="alert">{{ error }}</div>
{% endfor %}
{% endif %}
</p>
{% endmacro %}
Adding your own macro is pretty simple. For example, you can put custom macros in a "custom_macros.html" file within the templates directory and then load the functions into templates with
{% from "custom_macros.html" import render_field_with_bootstrap_errors %}
This way, it is easy to modify the macros to use different Bootstrap features.

Render field errors in for loop with Flask-WTF

I would like to iterate over form's fields in a template and display fields with errors like this:
{{ form.hidden_tag() }}
{% for field in form if field.widget.input_type != 'hidden' %}
{% if form.errors.field %}
<div class="has-error"> {{ field.label }} {{ field(size=80, class_='form-control') }}</div>
<span style="color: red;">{{ form.errors.field.0 }}</span>
{% else %}
{{ field.label }} {{ field(size=80, class_='form-control') }}
{% endif %}
{% endfor %}
But that doesn't work for some reason- the form renders but the errors are not displayed.
I've already checked solutions here, and here, and also here and none of those have helped.
Could someone please advise how to fix my form to correctly render the errors?
The issue is in using form.errors.field. This would only be accurate in jinja if you had a field named field and not for any other names.
Fortunately, you're already iterating fields, and every field has a .errors property so the shortest solution is to simply use that property
Your code should look something like:
{{ form.hidden_tag() }}
{% for field in form if field.widget.input_type != 'hidden' %}
{% if field.errors %}
<div class="has-error"> {{ field.label }} {{ field(size=80, class_='form-control') }}</div>
<span style="color: red;">{% for error in field.errors %}{{ error }}{% if not loop.last %}<br />{% endif %}{% endfor %}</span>
{% else %}
{{ field.label }} {{ field(size=80, class_='form-control') }}
{% endif %}
{% endfor %}

Misaka template tags for Django - text wrapped in double quotes

I'd like to replace the standard Markdown implementation in a Django blog I'm building with Github-flavoured Markdown. I'd like to use Misaka, and I've thrown together my own custom template tags. Unfortunately, something has gone awry.
Here is my template tags file, which is in blog/templatetags/gfm.py. The __init__.py file is present in the same folder:
from django import template
from django.template.defaultfilters import stringfilter
import misaka as m
register = template.Library()
#register.filter(is_safe=True)
#stringfilter
def gfm(value):
rendered_text = m.html(value,
extensions=m.EXT_FENCED_CODE,
render_flags=m.HTML_ESCAPE)
return rendered_text
And here is one of my templates:
{% extends 'layout/base.html' %}
{% block header %}
{% endblock %}
{% block content %}
{% load gfm %}
{% if object_list %}
{% for post in object_list %}
<div class="post">
<div class="page-header">
<h1>{{ post.title }}</h1>
</div>
{{ post.text|gfm }}
<p>Posted {{ post.pub_date }}</p>
<p>
{% for category in post.categories.all %}
<a class="badge badge-info" href="/category/{{ category.slug }}/">{{ category.title }}</a>
{% endfor %}
</p>
</div>
{% endfor %}
<br />
<ul class="pager">
{% if page_obj.has_previous %}
<li class="previous">Previous Page</li>
{% endif %}
{% if page_obj.has_next %}
<li class="next">Next Page</li>
{% endif %}
</ul>
{% else %}
<div class="post">
<p>No posts matched</p>
</div>
{% endif %}
{% endblock %}
The outputted text is being returned wrapped in double quotes, which breaks the whole thing. Otherwise, the markup generated seems correct.
Where have I gone wrong here? I know it's not the data in the database as if I use pdb to get the values of value and rendered_text inside the function, they are rendered correctly. For example, here is the plain text version of one post, as printed by pdb:
u'A Python application:\r\n\r\n print "Hello world"'
And here is the version rendered in Markdown using Misaka:
u'<p>A Python application:</p>\n\n<pre><code>print "Hello world"\n</code></pre>\n'
I'm fairly experienced with Django, but I'm new to custom template tags.
Use autoescape tag.
{% autoescape off %}{{ post.text|gfm }}{% endautoescape %}
Alternatively you can use safe filter.
{{ post.text|gfm|safe }}

How do I hide the field label for a HiddenInput widget in Django Admin?

I've got a bit of Django form code that looks like this:
class GalleryAdminForm(forms.ModelForm):
auto_id=False
order = forms.CharField(widget=forms.HiddenInput())
And that makes the form field go away, but it leaves the label "Order" in the Django admin page. If I use:
order = forms.CharField(widget=forms.HiddenInput(), label='')
I'm still left with the ":" between where the field and label used to be.
How do I hide the whole thing?!
Oraculum has got it right. You shouldn't be cleaning this up on the client side. If it is clutter, then you shouldn't be sending it to client at all. Building on Oraculum's answer, you should use a custom form template because you you probably still want the hidden values in the form.
{% for field in form.visible_fields %}
<div>
{{ field.errors }}
<span class="filter-label">{{ field.label_tag }}</span><br>
{{ field }}
</div>
{% endfor %}
{% for field in form.hidden_fields %}
<div style="display:none;">{{ field }}</div>
{% endfor %}
Using a custom form template to control hidden fields is cleaner because it doesn't send extraneous info to the client.
I can't believe several people have suggested using jQuery for this...
Is it a case of: when the only tool you know is a hammer everything looks like a nail?
Come on, if you're going to do it from the client-side (instead of fixing the source of the problem in the back-end code) surely the right place to do it would be in CSS?
If you're in the admin site then it's a bit harder but if it's a regular page then it's easy to just omit the whole label from the form template, for example
If you're in the admin site then you could still override the as_table, as_ul, as_p methods of BaseForm (see django/forms/forms.py) in your GalleryAdminForm class to omit the label of any field where the label is blank (or == ':' as the value may be at this stage of rendering)
(...looking at lines 160-170 of forms.py it seems like Django 1.2 should properly omit the ':' if the label is blank so I guess you're on an older version?)
Try
{% for field in form.visible_fields %}
I think it's simpler to achieve the ":" label omission for HiddenInput widget by modifying class AdminField(object) in contrib/admin/helpers.py from :
if self.is_checkbox:
classes.append(u'vCheckboxLabel')
contents = force_unicode(escape(self.field.label))
else:
contents = force_unicode(escape(self.field.label)) + u':'
to :
if self.is_checkbox:
classes.append(u'vCheckboxLabel')
contents = force_unicode(escape(self.field.label))
else:
contents = force_unicode(escape(self.field.label))
#MODIFIED 26/10/2009
if self.field.label <> '':
contents += u':'
# END MODIFY
Check the answer at Create a hidden field in the admin site, it can be done without JavaScript by overriding admin/includes/fieldset.html From there, you can inject a CSS class, and do the rest.
In theory, you should be able to pass label_suffix into the form constructor. However, the Django admin ignores this.
You've been bitten by two bugs in Django: #18134 'BoundField.label_tag should include form.label_suffix' (fixed in trunk, should be in 1.6) and to a lesser extent #11277 Hidden fields in Inlines are displayed as empty rows.
Currently, the best solution is to override the admin fieldset template. Use a HiddenInput for your widget, then override the admin fieldset template (documented here). Just create a templates/admin/includes/fieldset.html with the following contents:
<fieldset class="module aligned {{ fieldset.classes }}">
{% if fieldset.name %}<h2>{{ fieldset.name }}</h2>{% endif %}
{% if fieldset.description %}
<div class="description">{{ fieldset.description|safe }}</div>
{% endif %}
{% for line in fieldset %}
<div class="form-row{% if line.fields|length_is:'1' and line.errors %} errors{% endif %}{% for field in line %}{% if field.field.name %} field-{{ field.field.name }}{% endif %}{% endfor %}">
{% if line.fields|length_is:'1' %}{{ line.errors }}{% endif %}
{% for field in line %}
<div{% if not line.fields|length_is:'1' %} class="field-box{% if field.field.name %} field-{{ field.field.name }}{% endif %}{% if not field.is_readonly and field.errors %} errors{% endif %}"{% endif %}>
{% if not line.fields|length_is:'1' and not field.is_readonly %}{{ field.errors }}{% endif %}
{% if field.is_checkbox %}
{{ field.field }}{{ field.label_tag }}
{% else %}
{# only show the label for visible fields #}
{% if not field.field.is_hidden %}
{{ field.label_tag }}
{% endif %}
{% if field.is_readonly %}
<p>{{ field.contents }}</p>
{% else %}
{{ field.field }}
{% endif %}
{% endif %}
{% if field.field.help_text %}
<p class="help">{{ field.field.help_text|safe }}</p>
{% endif %}
</div>
{% endfor %}
</div>
{% endfor %}
</fieldset>
Based upon the solution by Wilfried Hughes I 've changed the fieldset.html with little improvements.
The code snippet below not only hides the input element instead if the fieldset contains only one single element which input-type is set to hidden it also hides the surrounding div-elements wasting no space in the form.
<fieldset class="module aligned {{ fieldset.classes }}">
{% if fieldset.name %}<h2>{{ fieldset.name }}</h2>{% endif %}
{% if fieldset.description %}
<div class="description">{{ fieldset.description|safe }}</div>
{% endif %}
{% for line in fieldset %}
<div class="form-row{% if line.fields|length_is:'1' and line.errors %} errors{% endif %}{% for field in line %}{% if field.field.name %} field-{{ field.field.name }}{% endif %}{% endfor %}"{% if line.fields|length_is:'1' %}{% for field in line %}{% if field.field.is_hidden %} style="display: none"{% endif %}{% endfor %}{% endif %}>
{% if line.fields|length_is:'1' %}{{ line.errors }}{% endif %}
{% for field in line %}
<div{% if not line.fields|length_is:'1' %} class="field-box{% if field.field.name %} field-{{ field.field.name }}{% endif %}{% if not field.is_readonly and field.errors %} errors{% endif %}"{% endif %}{% if field.field.is_hidden %} style="display: none"{% endif %}>
{% if not line.fields|length_is:'1' and not field.is_readonly %}{{ field.errors }}{% endif %}
{% if field.is_checkbox %}
{{ field.field }}{{ field.label_tag }}
{% else %}
{# only show the label for visible fields #}
{% if not field.field.is_hidden %}
{{ field.label_tag }}
{% endif %}
{% if field.is_readonly %}
<p>{{ field.contents }}</p>
{% else %}
{{ field.field }}
{% endif %}
{% endif %}
{% if field.field.help_text %}
<p class="help">{{ field.field.help_text|safe }}</p>
{% endif %}
</div>
{% endfor %}
</div>
{% endfor %}
The following removes the ':' from all your form fields. I've only tried it with the forms.Form class, but I believe it should work for forms.ModelForm too.
In Django forms, the ':' after the labels is the label_suffix. You can change or remove the label_suffix by creating a subclass of ModelForm, here called UnstyledForm, and redefining the initialization function with label_suffix set to an empty string. Then use your new UnstyledForm class.
class UnstyledForm(forms.ModelForm):
def __init__(self, *args, **kwargs):
kwargs.setdefault('label_suffix', '')
super(UnstyledForm, self).__init__(*args, **kwargs)
class GalleryAdminForm(UnstyledForm):
auto_id=False
order = forms.CharField(widget=forms.HiddenInput())
I hope that helps!
Another way to do it, but i think it still better to iterate form.visible_fields & form.hidden_fields
<form action="{% url 'some_url' param %}" method="POST">
{% csrf_token %}
<div class="row">
{% for field in form %}
{% if not field.is_hidden %}
<div class="col-md-6">
{{ field.label_tag }}
{{ field.error }}
{{ field }}
</div>
{% else %}
{{ field }}
{% endif %}
{% endfor %}
</div>
</form>
If you're using JQuery this should do the trick:
Your form
TO_HIDE_ATTRS = {'class': 'hidden'}
class GalleryAdminForm(forms.ModelForm):
auto_id=False
order = forms.CharField(widget=forms.TextInput(attrs=TO_HIDE_ATTRS))
Javascript code to add to your template
$(document).ready(function(){
$('tr:has(.hidden)').hide();
});
That works if you're rendering your form as a table. If you want to make it work with any kind of form rendering you can do as follows:
$(document).ready(function(){
$('{{ form_field_container }}:has(.hidden)').hide();
});
And add form_field_container to your template context. An example:
If you render your form like this:
<form>
<span>{{ field.label_tag }} {{ field }}</span>
</form>
Your context must include:
'form_field_container': 'span'
You get the idea...

Categories

Resources