FOSUserBundle resetting e-mail HTML template does not work - fosuserbundle

I am trying to define my own template for e-mail that is sent when user request for password, but it does not work when adding HTML part.
This is the template:
{% trans_default_domain 'FOSUserBundle' %}
{% block subject %}
{% autoescape false %}
{{ 'resetting.email.subject'|trans({'%username%': user.username, '%confirmationUrl%': confirmationUrl}) }}
{% endautoescape %}
{% endblock %}
{% block body_text %}
{% autoescape false %}
{{ 'resetting.email.message'|trans({'%username%': user.username, '%confirmationUrl%': confirmationUrl}) }}
{% endautoescape %}
{% endblock %}
{% block body_html %}
{% autoescape false %}
<div dir="ltr" style="display: block; width: 100%; background: #ffffff">
<table style='width: 100%; border: none'>
<tr style='height: 20px; background-color: #5A82FF'>
<td></td>
</tr>
<tr>
<td style="padding: 30px 0; font-family: Verdana">
{{ 'resetting.email.message_html'|trans({'%username%': user.username, '%confirmationUrl%': confirmationUrl}) }}
</td>
</tr>
<tr style='height: 20px; background-color: #4ED53E'>
<td></td>
</tr>
</table>
</div>
{% endautoescape %}
{% endblock %}
When the password request is sent, the mail is received in text format with both parts embedded in it, this way:
Estimado jstuardo#desytec.com!
Para restablecer tu contraseña - por favor visita http://xxx.xxx.xxx.xxx
Atte,
El equipo de XXX
<div dir="ltr" style="display: block; width: 100%; background: #ffffff">
<table style='width: 100%; border: none'>
<tr style='height: 20px; background-color: #5A82FF'>
<td></td>
</tr>
<tr>
<td style="padding: 30px 0; font-family: Verdana">
Estimado jstuardo#desytec.com!
<br /><br />
Para restablecer tu contraseña - por favor visita http://xxx.xxx.xxx.xxx
<br /><br />
Atte,<br />
El equipo de XXX
</td>
</tr>
<tr style='height: 20px; background-color: #4ED53E'>
<td></td>
</tr>
</table>
</div>
What may be wrong?
Thanks
Jaime

I ran into a similar problem.
The default mailer only supports sending plain text messages. If you want to send multipart messages, the easiest solution is to use the TwigSwiftMailer implementation instead. It expects your twig template to define 3 blocks:
subject containing the email subject
body_text rendering the plain text version of the message
body_html rendering the html mail
You must set the service in the config (e.g. app/config/config.yml)
fos_user:
# ...
service:
mailer: fos_user.mailer.twig_swift

Related

django for loop item list value check

I want to check if all for loop objects from below model and template have either signed or rejected the record. i.e. can you tell me how to check approve or reject field value for moc.verifiers.all list members?
For instance I have a three verifiers in the record. I want to based on their approve or reject change record status. Could you please give me a hint how I can do it.
Verifier
class Verifier(models.Model):
moc = models.ForeignKey(Moc, related_name='verifiers', on_delete=models.CASCADE, default='1')
verifier_group = models.CharField(max_length=36, blank=True, null=True)
verifier_name = models.ForeignKey(User, blank=True, null=True, on_delete=models.CASCADE,)
verify_due = models.DateField(blank=True, null=True)
approve = models.BooleanField(default=False)
reject = models.BooleanField(default=False)
signoff_date = models.DateField(auto_now_add=True)
note = models.TextField(max_length=256, blank=True)
def __str__(self):
return str(self.id)
Template
{% for obj in moc.verifiers.all %}
<tr style="text-align: center; FONT-SIZE: 7pt; BORDER-TOP: lightgrey 1px solid; HEIGHT: 25px; FONT-FAMILY: Verdana; BORDER-RIGHT: lightgrey 1px solid; BORDER-BOTTOM: lightgrey 1px solid; COLOR: #333333; BORDER-LEFT: lightgrey 1px solid"
valign="middle">
<td>
<form method="post" action="{% url 'delete_verifier' obj.pk %}">
{% csrf_token %}
<a href="{% url 'add_verify_signoff' obj.pk %}" target="_blank" type="button"
class="col-4 btn btn-primary p-1">
<i class="bi bi-pencil-square"></i>
</a>
<button type="button" class="col-4 btn btn-danger p-1" style="color: whitesmoke;" data-bs-toggle="modal"
data-bs-target="#delete-verifier"><i class="bi bi-trash"></i></button>
<!-- Modal -->
<div class="modal fade" id="delete-verifier" data-bs-backdrop="static" data-bs-keyboard="false"
tabindex="-1" aria-labelledby="staticBackdropLabel" aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header" style="background-color: #e6990a; height: 30px;">
<h5 class="modal-title" id="staticBackdropLabel" style="color: whitesmoke;">Notification
</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
</div>
<div class="modal-body">
<p style="font-size: medium;">Are you sure that you want to delete this verifier?</p>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Cancel</button>
<button type="submit" class="btn btn-primary">Confirm</button>
</div>
</div>
</div>
</div>
</form>
{% endif %}
</td>
<td style="WIDTH: 12%">{{ forloop.counter }}{{ obj.verifier_group }}</td>
<td style="WIDTH: 110px">{{ obj.verifier_name }}</td>
<td style="WIDTH: 110px">{{ obj.verify_due|date:'d M Y' }}</td>
{% if obj.approve %}
<td style="WIDTH: 20px"><input class="form-check-input-bg" type="checkbox" value="{{ obj.approve }}" checked
onclick="return false"></td>
<td style="WIDTH: 20px"><input class="form-check-input-bg" type="checkbox" value="{{ obj.reject }}"
onclick="return false">
{% elif obj.reject %}
<td style="WIDTH: 20px"><input class="form-check-input-bg" type="checkbox" value="{{ obj.approve }}"
onclick="return false"></td>
<td style="WIDTH: 20px"><input class="form-check-input-bg" type="checkbox" value="{{ obj.reject }}" checked
onclick="return false">
</td>
{% else %}
<td style="WIDTH: 20px">
<input class="form-check-input-bg" type="checkbox" value="" disabled>
</td>
<td style="WIDTH: 20px">
<input class="form-check-input-bg" type="checkbox" disabled onclick="return false">
</td>
{% endif %}
<td style="WIDTH: 90px">{{ obj.signoff_date|date:'d M Y'}}</td>
<td style="WIDTH: 200px">{{ obj.verifier_name }}</td>
<td style="WIDTH: 200px; text-align: justify;">{{ obj.note }}</td>
{% empty %}
<td colspan="8" style="WIDTH: 130px">No verifiers assigned yet...
</td>
</tr>
{% endfor %}

Pagination for the objects returned in 'else' clause

I have following model, where pagination works ok only if I don't filter by tags. As soon as I filter ads by tags, pagination doesn't work.
class AdListView(ListView):
paginate_by = 2
model = Ad
context_object_name = 'ads'
def get_context_data(self, **kwargs):
if self.request.GET.get('tags') is None:
context = super().get_context_data(**kwargs)
context.update(tags=Tag.objects.all())
return context
else:
tag_submitted = Tag.objects.get(name=self.request.GET.get('tags'))
ads_by_tag = tag_submitted.related_ads.all()
context = {
'ads': ads_by_tag
}
context.update(tags=Tag.objects.all())
return context
What needs to be done so that pagination works for both cases, with and without filter?
below are models.py and template
models.py
class Tag(BaseModel):
def __str__(self):
return str(self.name)
class Ad(BaseModel):
name = models.CharField(max_length=100)
description = models.TextField(max_length=500)
category = models.ForeignKey(Category, on_delete=models.CASCADE)
seller = models.ForeignKey(Seller, on_delete=models.CASCADE)
date_created = models.DateField(auto_now_add=True)
date_modified = models.DateField(auto_now=True)
tags = models.ManyToManyField(Tag, related_name='related_ads')
price = models.PositiveIntegerField(default=0)
archived = models.BooleanField(default=False)
def __str__(self):
return str(self.name)
class Meta:
ordering = ['-date_created']
template
{% block content %}
<div class="container">
<div class="row">
<div class="w-75">
<table class="table">
<thead>
<tr>
<th scope="col">#</th>
<th scope="col">Title</th>
</tr>
</thead>
<tbody>
{% for ad in ads %}
<tr>
<td>{{ forloop.counter }}</td>
<td> {{ ad.name }} </td>
</tr>
{% empty %}
<li>No ads yet.</li>
{% endfor %}
</tbody>
</table>
</div>
<div class="w-25">
<table class="table">
<thead>
<tr>
<th scope="col">Tags</th>
</tr>
</thead>
<tbody>
{% for tag in tags %}
<tr>
<td> {{ tag }} </td>
</tr>
{% empty %}
<li>No tags yet.</li>
{% endfor %}
</tbody>
</table>
</div>
</div>
<div class="row">
<div class="pagination">
<span class="step-links">
{% if page_obj.has_previous %}
« first
previous
{% endif %}
<span class="current">
Page {{ page_obj.number }} of {{ page_obj.paginator.num_pages }}.
</span>
{% if page_obj.has_next %}
next
last »
{% endif %}
</span>
</div>
</div>
</div>
{% endblock %}
so this is a project to learn django, so any other comments on how to improve the code also welcome.
You should not filter in the .get_context_data() [Django-doc]. In Django you pass the (possibly) filtered queryset in .get_queryset(…) [Django-doc]. Django will then paginate the queryset, and add it to the context. By overriding the item in the context, you now have removed the paginated queryset, and added a filtered queryset instead.
You thus provide the filtered queryset, and let Django do the proper pagination:
class AdListView(ListView):
paginate_by = 2
model = Ad
context_object_name = 'ads'
def get_search_querystring(self):
copy = self.request.GET.copy()
copy.pop(self.page_kwarg, None)
return copy.urlencode()
def get_queryset(self, *args, **kwargs):
qs = super().get_queryset(*args, **kwargs)
if 'tags' in self.request.GET:
return qs.filter(tags__name=self.request.GET['tags'])
return qs
def get_context_data(*args, **kwargs):
return super().get_context_data(*args, tags=Tag.objects.all(), **kwargs)
Another problem is the link in the template: by using ?page={{ page_obj.next_page_number }}, this will "drop" the query string [wiki] that contains the search query, and only use page as the only variable in the query string.
In the template we thus can use the URL as:
<a href="?page={{ page_obj.next_page_number }}&{{ view.get_search_queryset|safe }}">
the same should happen with the other pagination links.

wagtail 'your first site': how do I link to original of gallery image?

In the getting started tutorial for wagtail there is the following code in a template:
{% for item in page.gallery_images.all %}
<div style="float: left; margin: 10px">
{% image item.image fill-320x240 %}
<p>{{ item.caption }}</p>
</div>
{% endfor %}
Please excuse me if I'm missing something obvious but I can't find out how to do this in the docs. How would I link to the original file? eg:
{% image item.image fill-320x240 %}
You'll want to use the {{ img.url }} property in your template.
{% for item in page.gallery_images.all %}
<div style="float: left; margin: 10px">
{% image item.image fill-320x240 as img %}
<p>{{ item.caption }}</p>
{% comment %}
Assign your image `as img` (doesn't need to be `img`, you can
use any alias you'd like
{% endcomment %}
<img href="{{ img.url }}" alt="{{ img.alt }}" />
This is the link to your image
</div>
{% endfor %}
By assigning your image an alias, such as as img (in the code above) you can use {{ img.property_name }} in your template.

Proper way to fill an html array using django/python

I encounter a small issue about filling my html array in a django template.
I wanted to print one form to one row. Instead of one row to all forms ( that's what i get with the sample code just right there ) :
<thead> <!-- cétait td à la place de th -->
<tr>
{% for entry in headers %}
<th>
{{ entry }}
</th>
{% endfor %}
</tr>
</thead>
<tbody>
<tr>
{%for entry in entries%}
{%for cle, valeur in entry.all_form_entry_json%}
{%for key, valor in headersLoop%}
{%if key == cle%}
<td> {{valeur}}</td>
{% endif %}
{% endif %}
{% endfor %}
{% endfor %}
{% endfor %}
</tr>
</tbody>
The result is such as follow :
You can notice that all the datas are printed to the right corner and go beyond the array limit.
How can i have a result like this ?
Is this possible to do it only with html ? Or should i create a js or css file and import it to this template.html ?
Thank you for your answers !
I think you just wrong place for the html <tr> tag,
the tag <tr> should inside {% for loop..
<thead>
<tr>
{% for entry in headers %}
<th>{{ entry }}</th>
{% endfor %}
</tr>
</thead>
<tbody>
{% for entry in entries %}
<tr>
{% for cle, valeur in entry.all_form_entry_json %}
{% for key, valor in headersLoop %}
{% if key == cle %}
<td>{{ valeur }}</td>
{% endif %}
{% endfor %}
{% endfor %}
</tr>
{% endfor %}
</tbody>

Jekyll and Liquid - Filling table rows with array

I'm having some trouble filling table rows with an array.
What I would like to achieve:
The header row and the first column work fine, but I don't get the numbers right, that the first row contains ONLY the first number of the array (i.e. 50), the second row only the second number from the array etc.
My code:
---
exercises: [Burpees, Squats, Pull ups, Push ups]
rounds: 5
reps: [50, 40, 30, 20, 10]
---
<table class="responsive-table">
<thead>
<tr>
<th scope="col">Round</th>
{% if page.exercises %}
{% for exercise in page.exercises %}
<th scope="col">{{ exercise }}</th>
{% endfor %}
{% endif %}
</tr>
</thead>
<tbody>
{% for n in (1..{{page.rounds}}) %}
<tr>
<th scope="row">Round {{ n }}</th>
<!-- THIS PART DOESNT WORK
{% for exercise in page.exercises %}
<td data-title="{{ exercise }}"> {{ page.reps }} </td>
{% endfor %}
-->
</tr>
{% endfor %}
</tbody>
</table>
How can I fill the cells the way in the picture?
exercises: [Burpees, Squats, Pull ups, Push ups]
reps: [50, 40, 30, 20, 10]
---
<table class="responsive-table table">
<thead>
<tr>
<th scope="col">Round</th>
{% for exercise in page.exercises %}
<th scope="col">{{ exercise }}</th>
{% endfor %}
</tr>
</thead>
<tbody>
{% assign total = 0 %}
{% for rep in page.reps %}
{% assign total = total | plus: rep %}
<tr>
<th scope="row">Round {{ forloop.index }}</th>
{% for exercise in page.exercises %}
<td data-title="{{ exercise }}"> {{ rep }} </td>
{% endfor %}
</tr>
{% endfor %}
</tbody>
<tfoot>
<tr>
<th scope="row">Sum</th>
{% for exercise in page.exercises %}
<td>{{ total }}</td>
{% endfor %}
</tr>
</tfoot>
</table>

Resources