How to use base64 encoded markers with Leafletjs - django

I'm using leaflet to render government maps and adding custom markers via a Python backend. These markers are created using
var markers = {
{% for marker in markers.all %}
'{{ marker.slug }}': L.icon({
iconUrl: '{{ marker.icon.get_absolute_url }}',
{% if marker.shadow %}
shadowUrl: '{{ marker.shadow.get_absolute_url }}',
{% endif %}
}),
{% endfor %}
I'm trying to send the icons for the markers as base64 encoded PNGs to save a roundtrip request to the server for each icon of each map of each user accessing the maps. I've tried sending the images base64 encoded in a way similar as how Google Maps supports it (Marker Using base64 encoded string) with no success, the map rendering aborts with "Uncaught SyntaxError: Unexpected token ILLEGAL".
EDIT:
One possible solution: Extend Leaflet's Icon class
https://github.com/cavis/leafpile/blob/master/src/LeafpileIcon.js#L28

The problems was caused by the way I was converting the images to base64.
Instead of
base64.b64encode(contents)
I was using:
contents.encode('base64')
which inserts new line characters ('\n') causing the "Unexpected token ILLEGAL" Javascript error. Leaflet 0.7 supports base64 encoded marker icons correctly.

Related

Displaying Filepaths Correctly in Flask/Jinja2

I have a setup in a flask app where I can use a form to upload a file into the static/img directory for my application, and the metadata is stored in a record in a database.
When someone makes a request to the appropriate page, I want to read the file from the server using the filepath saved in the database.
Here's an example of the record when it's pulled from the database:
(3, 'My Info', 'My Description', 'www.url.com', 'static\\img\\aws_nameservers.PNG')
What I'd like to do is combine the last item in the above record with the url_for function to render the image stored at that location.
What I have right now is a set method that gets the last part of the file path:
{% set filepath = workshop_info[4][7:] %}
This returns img\\aws_nameservers.PNG
Then inside an img tag I have the following:
<img src="{{ url_for('static', filename=filepath) }}">
Which gives me the following result:
<img src="/static/img%5Caws_nameservers.PNG">
It seems like a simple thing, but I can't figure out how to render the string correctly inside the jinja2 template.
Thank you.
If there is a better approach than what I'm attempting, I'm happy to get corrected.
You should use the forward slash (/) instead of backslash (\) at the file path. You can replace them either in the Python code or in the template using a filter, e.g.:
{% set filepath = "img\\aws_nameservers.PNG" | replace("\\", "/") %}
{{ url_for('static', filename=filepath) }}
# Outputs: /static/img/aws_nameservers.PNG
You can also use the pathlib module to convert between the Windows and Unix style paths.

Send an email html containing an image with webform in drupal 8

I have a webform form that sends emails in html format with attachments.
For that, I use the modules Mail System and Mime mail. Everything works well.
For the body of the mail I use the option Twig Template and again everything works well ... except that I can not put an image (a logo) in the body.
I tried a lot of things and nothing works!
Every time I find myself with an empty tag!
How to integrate the image of the logo into the body of my email?
Thanks for your help
I was able to include the Drupal logo without any problem using the below Twig template.
<img src="https://www.drupal.org/files/druplicon-small.png"/>
<hr/>
<p>Submitted on {{ webform_token('[webform_submission:created]', webform_submission) }}</p>
<p>Submitted by: {{ webform_token('[webform_submission:user]', webform_submission) }}</p>
<p>Submitted values are:</p>
{{ webform_token('[webform_submission:values]', webform_submission) }}
The img tag is not stripped out. My only guess is the image's src is not using an absolute URL

django, secondary data in subfolders

I am working on an informational site. I am attempting to access files in a subdirectory using data from the django db.
Ex: if the record.id = 1 and the file is desc.txt, I want to grab /1/desc.txt
I currently have two items that I'm trying to access this way. The image file will work if I hard code the location, but I haven't been able to get it to work from the record data. The other one, I'm trying to load a description file into a div using jQuery and .html(), and can't get it to work at all.
The relevant section of code:
{% if aRecord %}
{% load static from staticfiles %}
<h1>{{ aRecord.Name }}</h1>
<br/>
Born: {{aRecord.Birth}}<br/>
Died: {{aRecord.Death}}<br/>
<div id="descArea"><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/></div>
<script>
descfile = 'Authors/1/desc.txt';
$('#descArea').text(descfile);
$.get("{% static 'Authors/1/desc.txt' %}", function(data) {
$('#descArea').html(data);
});
</script>
<br/>
{% else %}
Requested author not found.
{% endif %}
This is the hard-coded version that works, but I need it to work from the aRecord data. The 1 in both cases should come from the record id, and the image filename in the img tag should as well.
It sounds like this is really a question about how to produce a file path from dynamic data. Is that the case? If so, you will probably need to use string substitution.
In order to produce a string like '/1/desc.txt' where the 1 is given by a record id, you could do something like this:
path = '/{}/desc.txt'.format(record.id).

How to run a filter over the property of my Django Model?

I am working with a Model has a payload property which contains a Base64 encoded JSON.
I am writing admin views which will consolidate data represented by this model and several others.
I want to display the Base64 decoded version of the JSON in ModelAdmin views.
I also want to run a query which would return rows such that a specific element in the decoded JSON matches a value.
Is this doable in Django ?
You have to create a custom admin template with the following code:
{% extends "admin/change_form.html" %}
{% load i18n %}
{% block content %}
This is the field: {{ original.payload }}
{{ block.super }}
{% endblock %}
save it as, say, "templates/admin/change_model_payload.html" and add this to the model's ModelAdmin:
change_form_template = "admin/change_model_payload.html"
For #2, you might want to create a custom template tag to retrive the DB entries.
If you expect a specific element of a specific type, then you'd better decode it on save() than to blindly store it in base64.
There is no easy way to get info from base64-encoded data.
base64 does not align on bytes boundaries, so you can't look at the encoded data and say "ah, there starts the property xxx!"
json should already have its binary data encoded in base64, so you shouldn't encode it again in base64.
My advice is to create a PayloadData class with all the expected attributes, with a one-to-one to your original model, where you store the attributes upon save()ing the payload, and where you can index, query, filter, order, join and any other interesting things a RDBMS allows you to do.
OR ditch you database and Django's own ORM and go no-sql. Most document-based nosql servers have the ability to query (or at least create views) for any kind of subfield condition.

Sending localized messages to Django users

I'm having trouble with sending localized messages to Django users using the
user.message_set.create(message="Message")
mechanism. First of all,
user.message_set.create(message=_("Message"))
flat out doesn't work, SQLite says it won't accept the non-ascii parameter (localized message contains special characters).
user.message_set.create(message=unicode(_("Message")))
sends the original English message regardless of the preferred language (other translated parts of the app do work correctly).
Using a hardcoded localized message like this
user.message_set.create(message=u"Localized message áýčš")
is the only thing that works but that implies that I'd be able to only use one language.
How can I send users localized messages loaded from LC_MESSAGES?
Have you tried localizing the message right before you display it?
In your view:
user.message_set.create(message="Message")
In your template
{% if messages %}
<ul>
{% for message in messages %}
<li>{% trans message %}</li>
{% endfor %}
</ul>
{% endif %}
This way, you don't have to store any odd characters in your database.
user.message_set.create(message=_("Message"))
... should work. Are you using the latest version of SQLite, does UTF-8 support have to be enabled somehow? Are you storing non-ascii characters in SQLite elsewhere?