Wagtail Image template tags - django

I'm using Django-variant CMS Wagtail and am trying to build my own templates for it.
I can upload images into the rich text field in Wagtail's CMS as shown:
In my template's html, I would like to be able to call specific images uploaded in the body so that I can style those specific images differently with js.
perhaps something like {{ body.image }}?
the html:
{% extends 'wagweb/base.html' %}
{% load rich_text static compress cache image_tags pageurl %}
{% block content %}
<div class="box">
<article class ="content">
{{ self.body | richtext }}
</article>
</div>
{% endblock %}
I'm lost at this point, as I can't figure out how to find the pre-existing tag dictionary (if there is any) or to create one without messing with the views.py? Or would it be more straight-forward to install markdown into the richtextfield and work from there?
I'm tons more comfortable with html and css, so one solution is to simply write everything in html and use {{ MEDIA_URL }} to call the specific images. But that seems like an unintelligent way to use Wagtail and Django.

Currently the rich text editor doesn't support embedded images with custom attributes (like CSS classes). It also doesn't provide a HTML source editor for the richtext field.
However, if you don't need to have the images inline with the rich text (but rather before or after the text, you could include them in your page model using InlinePanel pointing to table which uses a ParentalKey. Then, in your templates, you could loop through multiple images and apply the specialized CSS classes. The Wagtail demo project uses this method to create an image carousel. You can find some explanation on the more general tactic of using ParentalKey/InlinePanel here in the Editing API.

Related

Is it possible to display the HTML provided by the admin panel app on-site?

I've built a site where I can create new posts (essays) by the admin panel. The output is visible to users. But when I place some HTML as content in the form it doesn't render itself on the page.
example:
Output on the page (with marked unrendered HTML):
I would like to know how to fix it and also, how to name the topic I want to know ( I couldn't find anything related to my problem, probably because I don't know how to express it).
Additionally, I just start to wonder if there is one more problem nested inside. How to link CSS from the static folder having this HTML mentioned above?
Django offer the autoescape template in the builtins tags
{% autoescape off %}
{{ myhtml }}
{% endautoescape %}
But your logic seems wrong, you don't need to create a new page with the doctype, just create a base template and use the block content tag to insert your article.
In your base template replace the description and title of your page by variables that will be populated by the article data.
You need to learn the basic of Django https://docs.djangoproject.com/en/4.1/ trust me you won't regret it !

Django HTML snippet for a model

I am new to Django and I am trying to find out how can I associate a HTML snippet with a model.
My HTML snippet is just a div. I want to reuse that div (you can think of it like a thumbnail)
Situation is like this: In my main page I want to show x objects and in my search page I want to show more objects. But the representation is the same.
I can write in the mainpage.html and searchpage.html the desired way of transforming the model object into a div but I am not sure what is the best way to reuse that transform?
I can add a function to my model which returns a HTML div, then I can call it from mainpage and searchpage templates. But that will couple the model and representation, which I believe is not a very nice thing to do.
If I am not mistaken inclusion_tags are the way to go but in which file should I keep the function definition?
As you rightly say, you don't want html in your models, it's goes against the MVC pattern.
Models are for storing data. Views are for selecting the data to present whilst Templates are used for the actual presentation of data. (See this note on django's interpretation of MVC).
To answer your question, you need a template (or even a template tag), to represent your model, say model_block.html. Something like
{% if obj %}
<div id=obj.id>
{{ obj.name }}
</div>
{% endif %}
Then include your template in your mainpage.html like
{% for obj in object_list %}
{% include 'model_block.html' %}
{% endfor %}
You can do the same thing in your searchpage.html, passing a different object_list variable from your view.

Django-CMS - Global placeholder?

Is there any way to make global placeholder in my base template? I need it to be the same on every page (banners list).
How can I do that?
I usually create a page in my CMS that isn't published, but contains placeholders that I would like to use elsewhere (footer/headers) etc.
Make a new template extra_placeholders.html:
{% extends "base.html" %}
{% load cms_tags %}
{% block content %}
{% placeholder "Banner-List" %}
{% endblock %}
add it to your settings:
CMS_TEMPLATES = (
('my/path/extra_placeholders.html', 'Extra Placeholder Page'),
...
)
now go to the admin and create the placeholder with whatever plugin you want. Then go to you base template (*base.html probably) from which all your other pages inherit and add this wherever you want the placeholder to appear:
{% load cms_tags %}
...
{% show_placeholder "Banner-List" "extra_placeholders" %}
You can read more about it in the docs
EDIT
As #José L. Patiño has mentioned in the comments, this solution is only necessary for those using django-cms < 3.0. For the newer version you can simply use the static_placeholder template tag
There is the "static_placeholders" now, http://docs.django-cms.org/en/latest/reference/templatetags.html#static-placeholder
Sounds like it's what you needed way back when.
You can use the following ways to create a global palceholder for all pages.
create a place holder on the base page. {% Placeholder "footer"%}
make the contents of the placeholder through django cms as home page
then to display the same for each placeholder page, add {% show_placeholder "footer" "home"%}, this means displaying the newly created footer placeholder earlier from the home page,
This will display the entire contents existing footer placeholders on the home page of all pages that use the template.
but for the home page there will be two footer is displayed, to mengilangkannya, please do modifications to use CSS to hide the master placeholder.

Django: Allow user to submit valid HTML in form field

With Django, is it possible for users to submit HTML in a form field, save it, and then render the HTML in the template?
An example is a user adding a link within a textfield that should then be rendered as an a tag within the rest of the text.
The user would input something like :
this is a site called SO.
The SO link would be a link instead of rendering it as text.
Django escapes by default. You can mark a string as safe via a filter or tag to prevent the auto escaping behavior.
{{ my_text_with_html|safe }}
{% autoescape off %}
{{ my_test_with_html }}
{% endautoescape %}
If you accept user inputted html, you'll want to sanitize it so they can't write scripts and such.. for that, just search python html sanitizing and apply it before sending the data to the template.
Python HTML sanitizer / scrubber / filter
You can tell Django the HTML is safe by marking it with the appropriate filter:
{{ variable|safe }}
You can also use the autoescape tag to disable the autoescaping:
{% autoescape off %}
{{ variable }}
{% endautoescape %}
However, in case you are enabling this feature for other (unknown) users, I highly recommend using something else, since HTML can be quite a pain to properly sanitize from Javascript or other HTML-things you don't want (e.g., on*-arguments etc). Django actually ships with basic support for some markup languages you can provide to your users. I guess markdown is being the most popular.

Django conditional template inheritance

I have template that displays object elements with hyperlinks to other parts of my site. I have another function that displays past versions of the same object. In this display, I don't want the hyperlinks.
I'm under the assumption that I can't dynamically switch off the hyperlinks, so I've included both versions in the same template. I use an if statement to either display the hyperlinked version or the plain text version. I prefer to keep them in the same template because if I need to change the format of one, it will be easy to apply it to the other right there.
The template extends framework.html. Framework has a breadcrumb system and it extends base.html. Base has a simple top menu system.
So here's my dilemma. When viewing the standard hyperlink data, I want to see the top menu and the breadcrumbs. But when viewing the past version plain text data, I only want the data, no menu, no breadcrumbs. I'm unsure if this is possible given my current design. I tried having framework inherit the primary template so that I could choose to call either framework (and display the breadcrumbs), or the template itself, thus skipping the breadcrumbs, but I want framework.html available for other templates as well. If framework.html extends a specific template, I lose the ability to display it in other templates.
I tried writing an if statement that would display a the top_menu block and the nav_menu block from base.html and framework.html respectively. This would overwrite their blocks and allow me to turn off those elements conditional on the if. Unfortunately, it doesn't appear to be conditional; if the block elements are in the template at all, surrounded by an if or not, I lose the menus.
I thought about using {% include %} to pick up the breadcrumbs and a split out top menu. In that case though, I'll have to include it all the time. No more inheritance. Is this the best option given my requirement?
You can put your hyperlinks inside a block that is overridden by the loading templates.
Let's say you have your framework.html like this:
{% extends "base.html" %}
<html>...<body>...
{% block hyperlinks %}
your hyperlinks here
{% endblock %}
rest of the code
</body></html>
You can then create something of a nolinks.html template and use it
{% extends "framework.html" %}
{# here you'll have everything from framework
but now we disable the breadcrumbs #}
{% block hyperlinks %}{% endblock %}
If you're getting the past data you can then use nolinks to render instead of framework.
I hope this helps.
From here: Any way to make {% extends '...' %} conditional? - Django
It can be done like this :
{% extends ajax|yesno:"ajax_base.html,main_base.html" %}
Or:
{% extends a_variable_containing_base_template_name %}
Which ever best suited for you.
Regards;