Django {{data|escapejs}} from a js static file - django

I use {{data|escapejs}} django banner to import some data in my the javascript of my page.
Simple example :
<script>
console.log({{data|escapejs}})
</script>
But it doesn't work if I place this line in a .js static file
<script src = "{% static 'mycode.js' %}>
In mycode.js :
console.log({{data|escapejs}})
How to make it work ?

Okeeyy ... finally, it was easy.
<script>
var myvar = {{data|escapejs}}
</script>
<script src = "{% static 'mycode.js' %}">

Related

django-compressor Uncaught SyntaxError: import declarations may only appear at top level of a module

This is my JS structure:
This is the beginning index.js
import { elements } from './views/base';
const state = {};
const controlRandomPhrasal = async () => {}
My base.js:
export const elements = {
searchFrom: document.querySelector('.search'),
}
I invoke the compressor like this:
{% compress js %}
<script src="{% static "phrasals/js/jquery.js" %}"></script>
<script src="{% static "phrasals/js/index.js" %}"></script>
{% endcompress %}
How can I configure my project to avoid that error?
Or can you suggest me an easier/better bundler?
After a while of being looking for a response. I choose to build my pipeline using Webpack and Babel. This is where I started:
Hybrid application, Django-Webpack

Add RTF/Rich Text Editor to CustomUserCreationForm/CustomUserEditForm

I try to extend my custom User model as described here.
This works fine for the shown fields like ModelChoiceField and CharField.
My goal now is to add a RTF field (the control like the one shown in the Page model). I have looked through the source code of wagtail and found the method get_rich_text_editor_widget which is being used in conjunction with a CharField. Sadly I get a JavaScript error:
Uncaught TypeError: Cannot read property 'initEditor' of undefined
My guess now is that I somehow need to include or modify a hook for the widget. Or is it sufficient to override the JavaScript block in a template? It feels a bit hacky right now and I am stuck with including the required JS, that's why I am posting the question. Maybe I am missing something trivial.
# ...
from wagtail.admin.rich_text import get_rich_text_editor_widget
class CustomUserEditForm(UserEditForm):
position = forms.ModelChoiceField(queryset=Position.objects, required=True, label=_('Position'))
# biography = forms.Textarea()
biography = forms.CharField(widget=get_rich_text_editor_widget())
Update:
Updating my template (maybe not the right approach):
{% block js %}
{{ block.super }}
<script type="text/javascript" src="/static/wagtailadmin/js/draftail.js"></script>
{% endblock js %}
Results in:
I've written my solution up as an issue for draftail
https://github.com/springload/draftail/issues/450
I've got a wagtail site with this awesome RichText Editor (called Draftail) but trying to use it on a non Wagtail Admin page makes me feel dirty. I wanted a biography field that people could write about themselves and I wanted the blog authors to be able to use it as well. BUT to do that I've had to do some things that make me cringe.
Not bad:
{% block extra_css %}
<link href="{% static 'wagtailadmin/css/panels/draftail.css' %}" type="text/css" media="all" rel="stylesheet">
{% endblock extra_css %}
WTF???? why aren't we just using Favicons for things like Bold
<div data-sprite></div>
<script>
function loadIconSprite() {
var spriteURL = '{% url "wagtailadmin_sprite" %}';
var revisionKey = 'wagtail:spriteRevision';
var dataKey = 'wagtail:spriteData';
var isLocalStorage = 'localStorage' in window && typeof window.localStorage !== 'undefined';
var insertIt = function (data) {
var spriteContainer = document.body.querySelector('[data-sprite]');
spriteContainer.innerHTML = data;
}
var insert = function (data) {
if (document.body) {
insertIt(data)
} else {
document.addEventListener('DOMContentLoaded', insertIt.bind(null, data));
}
}
if (isLocalStorage && localStorage.getItem(revisionKey) === spriteURL) {
var data = localStorage.getItem(dataKey);
if (data) {
insert(data);
return true;
}
}
try {
var request = new XMLHttpRequest();
request.open('GET', spriteURL, true);
request.onload = function () {
if (request.status >= 200 && request.status < 400) {
data = request.responseText;
insert(data);
if (isLocalStorage) {
localStorage.setItem(dataKey, data);
localStorage.setItem(revisionKey, spriteURL);
}
}
}
request.send();
} catch (e) {
console.error(e);
}
}
loadIconSprite();
</script>
Because wagtail comments.js somehow needs wagtailConfig.ADMIN_API and draftail won't initialize without comments.js
<script>
(function(document, window) {
window.wagtailConfig = window.wagtailConfig || {};
wagtailConfig.ADMIN_API = {
PAGES: '',
DOCUMENTS: '',
IMAGES: '',
{# // Use this to add an extra query string on all API requests. #}
{# // Example value: '&order=-id' #}
EXTRA_CHILDREN_PARAMETERS: '',
};
{% i18n_enabled as i18n_enabled %}
{% locales as locales %}
wagtailConfig.I18N_ENABLED = {% if i18n_enabled %}true{% else %}false{% endif %};
wagtailConfig.LOCALES = {{ locales|safe }};
wagtailConfig.STRINGS = {% js_translation_strings %};
wagtailConfig.ADMIN_URLS = {
PAGES: ''
};
})(document, window);
</script>
<script src="{% static 'wagtailadmin/js/vendor/jquery-3.5.1.min.js' %}"></script>
<!-- <script src="{% static 'wagtailadmin/js/core.js' %}"></script> strangely not needed -->
<script src="{% static 'wagtailadmin/js/vendor.js' %}"></script>
<script src="{% static 'wagtailadmin/js/comments.js' %}"></script>
{{ form.media.js }}
All of this just to get the draftail editor on a non wagtail admin page!

Using local MathJax files with Django / Mezzanine

I would like to load MathJax in my base template with:
<script type="text/x-mathjax-config">
MathJax.Hub.Config({
tex2jax: {inlineMath: [['$','$'], ['\\(','\\)']]}
});
</script>
<script type="text/javascript"
src="{% static "js/MathJax/MathJax.js?config=TeX-AMS-MML_HTMLorMML" %}">
</script>
However in the rendered template the URL is returned as:
/static/js/MathJax/MathJax.js%3Fconfig%3DTeX-AMS-MML_HTMLorMML
and MathJax doesn't work.
If I hard-code the URL as src="/static/js/MathJax/MathJax.js?config=TeX-AMS-MML_HTMLorMML" it works. How can I prevent Django/Mezzanine from escaping the ? and = characters? Is there an alternative approach?
[The reason I want to use a local MathJax is for development when I'm away from an internet connection; I use a CDN in production.]
I would try moving the config parameter outside the static reference and see if that helps:
<script type="text/javascript"
src="{% static "js/MathJax/MathJax.js" %}?config=TeX-AMS-MML_HTMLorMML">
</script>
I don't know Django or Mezzanine, but if the static is what is encoding the URL characters, moving them outside might prevent that.

Values from controller are not displayed

I am trying to introduce Angular in my Django app. I doubt, that my problem is directly correlated with interpolateProvider which is needed because of django templates... but who knows.
I also have a problem with simplified version of that: http://jsfiddle.net/33417xsm/
This is my current version:
<html ng-app="MyApp">
<head>
<script type="text/javascript" src="/static/js/libs/angular/angular.js"></script>
<script type="text/javascript" src="/static/js/app/app.js"></script>
</head>
<body>
<div ng-controller="MyAppController">
[[ 2 + 4 ]]
<p>[[ MyAppController.product.title ]]</p>
</div>
</body>
</html>
file: app.js
(function(){
var app = angular.module('MyApp', []);
app.config(function ($interpolateProvider) {
$interpolateProvider.startSymbol('[[');
$interpolateProvider.endSymbol(']]');
}
);
app.controller('MyAppController', function (){
this.product = gem;
});
var gem = {
'title': 'Inferno'
};
})();
My result:
As you can guess, I want to also display Inferno. What I am doing wrong?
Your app config is ok. But i see, you didn't understand clearly angular concept.
You must use $scope to binding data. Also you never need "myController.product" like this notation.
I updated your code http://jsfiddle.net/33417xsm/4/
<div ng-app="MyApp" ng-controller="MyAppController">
{{ 2 + 4 }}
<p>{{product.title}}</p>
</div>
var app = angular.module('MyApp', []);
app.controller('MyAppController', function ($scope){
$scope.product = {"title":"product title"};
});

Assign JavaScript value to Django template tag argument

How do I assign an argument value to a Django template tag, using JavaScript?
{% url path.to.some_view arg=v %}
This doesn't work:
<script>
var v = 5;
</script>
{% url path.to.some_view arg=v %}
You can't.
By the time the browser has the HTML, and the javascript is being executed the django template has already been compiled serverside and the resulting html is being displayed by your browser.
This should work:
<script>
var v = 5;
var url = '{% url path.to.some_view 999 %}'.replace (999, v);
</script>
You could do something like:
< A HREF="{% reverse path.to.some_view %}&arg=" + document.v">Some_view< /A>