Customizing Wagtail Streamfield - django

Can anyone provide the code necessary to create the Wagtail Streamfield options that are previewed on the wagtail.io website front page?
https://media.wagtail.io/images/w1_5pmaP1U.original.width-1600.png
Specifically, I'm interested in Aligned Image, Wide Image, Bustout, Raw HTML, and Markdown.

This page describes how to freeform page content using StreamField (blocks).
https://docs.wagtail.io/en/latest/topics/streamfield.html
You can subclass any built-in block and provide your own template:
class WideImage(ImageChooserBlock):
class Meta:
label = 'Wide image'
icon = 'image'
template = 'website/blocks/wide_image.html'
The html is up to you:
{% load wagtailimages_tags %}
{% image self width-1024 as img %}
<img src="{{ img.url }}" class="image--wide">
Ofcourse the css is up to you too.
.image--wide { width: 100% }
What the exact markup and styling should be, depends on your current frontend markup and styling.
Aligned Image, Wide Image and Bustout can be achieved in the same way. Simple markup and little css.
Raw HTML is an existing block
https://docs.wagtail.io/en/latest/topics/streamfield.html#rawhtmlblock
You can store your markdown in a TextBlock.
https://docs.wagtail.io/en/latest/topics/streamfield.html#textblock
Converting markdown to html is a three line custom string filter:
#stringfilter
def md(value):
return markdown2.markdown(value)
Use it in your template:
{% load app_tags %}
{{ self|md }}

Related

Dynamic Wagtail bgcolor templatetags

I am trying to get a dynamic background color with Wagtail templatetags when I convert an image like this :
{% load wagtailimages_tags %}
{% image my_file width-768 format-jpeg bgcolor-171721 as image_jpeg %}
<img src="{{ image_jpeg.url }}"/>
How I can change the value bgcolor-171721 with a dynamic variable in my template ?
I do not think it is possible to have dynamic token parts for a Django Template tag.
However, you could generate the rendition with the dynamic parts at the request (page model). The wagtail docs explain how to generate a rendition in Python. The tokens are similar but generated as one string separated by the | character.
You can then pass this into the template's context via your page model's `get_context' method.
models.py
class MyPage(Page):
# ...
def get_context(self, request):
# Update context to include an image rendition with a dynamic bg
context = super().get_context(request)
# https://docs.wagtail.io/en/stable/advanced_topics/images/renditions.html
some_dynamic_value = 'DDA0DD'
context['image_jpeg'] = self.my_image.get_rendition('width-768|bgcolor-%s|format-jpeg' % some_dynamic_value)
# you can use this within the template the same way - <img src="{{ image_jpeg.url }}"/>
return context
You could go further and create a custom template tag that takes a dynamic background colour (or reads it from the template context) but that might not be worth the extra complexity.

Output Django Charfield as a responsive Bootstrap textarea

If I have a form containing a CharField and select the Textarea-widget, then I can specify the number of rows and columns for the textarea, but this output will not be responsive.
In short: How can I output my form field using Bootstrap's Textarea-widget or make the default one responsive.
what about setting max-width: 100%; on the textarea ?
EDIT after comments:
I still think the above method could be a simple and direct solution for your case, because it's easy to put that in the css and render all the forms responsive without overriding your field widget or the template for that field.
Otherwise you could consider using django-crispy-forms , and do something like:
{% load crispy_forms_tags %}
...
{{ form|crispy }}
or using the tag only on the desired field: {{ form.textfield|crispy }}
it will render your form with the bootstrap template if you set in your config CRISPY_TEMPLATE_PACK = 'bootstrap3'

Django Crispy forms and i18n in HTML Layout

I tried searching but could not find any answer to this, in Django crispy forms there is an HTML layout Object which allows you to inject customized HTML into your form, I am working on a CreateView Form which implements some arbitary creation of related elements, I inject the HTML under my field the following way:
HTML(
'''<p class="add">
{% trans 'Add a category' %}
</p>'''
),
My problem is that although url tags work ok, trans tags are not parsed within crispy forms, is there an alternative (maybe within crispy forms?) to maintain i18n?
In the form template there is proper i18n loading of tags:
{% load i18n %}
{% load crispy_forms_tags %}
Since you are trying to do it in some .py file (as i understood), then why do you bother with templatetags - use python.
injected_html = u"<p class='add'><a href='%(url)s'>%(translation)s</a></p>" % {'url':some_get_url_method(), 'translation':_(u"Add a category")}
HTML(injected_html)

How to display a couchdb image attachment in a Django template

I am using couchdb-python with Django. I am looking for a way to display an image (which is stored in the database as an attachment to a document) in a template. Oddly, I cannot find any example online of how to do this.
Currently, in the views.py I have something like this:
def displaypage(request,id):
docs = SERVER['docs']
try:
doc = docs[id]
except ResourceNotFound:
raise Http404
...
attachments = doc['_attachments']['someimage.jpg']
...
text_marked_down = markdown.markdown(doc['text'])
return render_to_response('couch_docs/display.html',{'row':doc,'attachments':attachments,'doctext':text_marked_down,...},context_instance=RequestContext(request))
Then, in the template display.html:
{% extends 'site_base.html' %}
{% block wrapper %}
{{ attachments }}
<div>{{ doctext|safe }}</div>
{{ endblock }}
I am seeing the text just fine, but for the image I only see the following:
{u'stub':True, u'length':27018,u'revpos':19,u'content_type': u'image/jpeg'}
So, clearly I am not passing the actual image, or not displaying it correctly anyway. Oddly, I cannot find an example online anywhere of how to actually do this. Can anyone point me to one, or provide it here?
You are using the template engine to render an HTML document. That document will be interpreted by the web browser just like any other HTML document.
Think about how an HTML page contains an image. The image is never inline within the HTML document itself. The HTML page contains a reference to instruct the browser to separately load the image and display it in place.
<img src="/path/to/image" />
So, likewise, you will need to:
create a separate view that will only return the binary data of the image. Set the mime type appropriately. See http://effbot.org/zone/django-pil.htm for some ideas how to return an image, but in your case set the contents of the response to be your image content.
add an <img ...> tag to your template that calls the new view you created.
once you drill down your db, you might want to consider building the url of each documents attachment as follows:
def function():
couch = couchdb.Server() #connect to server
db = couch['img'] #connect to database which contains docs with img attachments
doc_id = [] #create list of id's
http_docid = [] #create list to populate href for picture path
for i in db: #for each id in the db
doc_id.append(i) #add to the carid list
doc = db[i] #get the document id
for key in (doc['_attachments']): #for the key in the doc '_attacments' payload
print key #just to confirm
href_docid.append(('http://yourdbDomain/dbname/'+i+'/'+key)) #create a uri and append to a list
return href_docid
And below im using Jinja2's templating:
{% for img in function() %}
<img class="some-class" src="{{ img }}">
{% endfor %}
Hope this proves usefull!

Dynamically create and save image with Django and PIL/Django-Photologue

I want to generate a page of html with dynamic content and then save the result as an image as well as display the page to the user. So, user signs up to attend conference and gives their name and org. That data is combined with html/css elements to show what their id badge for the conference will look like (their name and org on top of our conference logo background) for preview. Upon approval, the page is saved on the server to an image format (PNG, PDF or JPG) to be printed onto a physical badge by an admin later. I am using Django and django-photologue powered by PIL.
The view might look like this
# app/views.py
def badgepreview(request, attendee_id):
u = User.objects.get(id=attendee_id)
name = u.name
org = u.org
return render_to_response('app/badgepreview.html',
{'name':name,'org':org,},
context_instance = RequestContext(request),
)
The template could look like this
{# templates/app/badgepreview.html #}
{% extends "base.html" %}
{% block page_body %}
<div style='background:url(/site_media/img/logo_bg.png) no-repeat;'>
<h4>{{ name }}</h4>
<h4>{{ org }}</h4>
</div>
{% endblock %}
simple, but how do I save the result? Or is there a better way to get this done?
The only thing I can think is to do it in two passes:
a) Use http://www.xhtml2pdf.com/ to convert the HTML into a PDF.
b) Use something like http://www.swftools.org/gfx_tutorial.html to convert the PDF into an image.
I can't imagine that doing this would be fast...
You might be better off just converting and allowing them to download a PDF (i.e. use just step a) above) or trying to generate the badge directly without the HTML intermediate step.