Simplified, structure of my project in regard to JavaScript usage is as follows:
base.html (project's base template)
{% block js %}{% endblock %}
<script type="application/javascript" src="/base.js"></script>
child.html (a template, that inherits from base.html)
{% block js %}
<script type="application/javascript">
{# context_variable is a JSON string generated by handler #}
specialObj = {{ context_variable|safe }};
</script>
{% endblock %}
base.js (project's main script)
function specialFn() {
// something is done with specialObj here...
}
if (specialObj)
specialFn();
Question is: should I redeclare obj in base.js for readability (or some other reason)?
I assume you mean specialObj? You are defining it as a global variable, so it is already available to base.js. No need to redeclare.
Related
I want to add custom JavaScript everytime as per the logic in my backend.
For example:
--views.py--
...
js="JavaScript which i want to add"
js_={'js_script':js}
return render(request,'html.html',context=js_)
--html.html--
....
<script>
{{js_script}}
</script>
But this does not properly work and a weird " is added in various places in the html source code everytime and the work is not accomplished. Please Help if you have a work around.
Just tried something and it worked.
source: django docs - safe templatetag
in context you are doing it right example:
context = {
'js_var': 'console.log("JavaScript which i want to add")',
}
in template add template tag "safe" it will remove the """ 's:
<script>
console.log('sanity check');
{{js_var|safe}}
</script>
output:
sanity check
JavaScript which i want to add
Have a good day!
Tell me if this worked for you!
i think you want to load custom javascript code locally for particular page, to do that the proper way without mixing things, you need to define {% block %} in your base.html template and via DTL inheritance mechanism you can load you javascript the right way in right order without any conflict
in base.html define, let say {% block javascripts_local %}{% endblock %} like
{% load static %}
<!doctype html>
<html class="no-js" lang="{% block lang %}en{% endblock %}">
<head>
[..]
</head>
<body{% block body_attributes %}{% endblock %}>
[..]
{% block javascripts %}
<!-- i'm using HTML5 Boiler Plate template -->
<script src="{% static 'js/vendor/modernizr-3.7.1.min.js' %}"></script>
<script src="{% static 'js/plugins.js' %}"></script>
<script src="{% static 'js/main.js' %}"></script>
<!-- override this block in child template -->
{% block javascripts_local %}{% endblock %}
{% endblock %}
</body>
</html>
and then in your child template override the block
{% extends 'base.html' %}
{% load static %}
[..]
{% block javascripts_local %}
<script>
// Your javascript code goes here
</script>
{% endblock %}
I'm having issues calling functions from twig views in Symfony 4.4. This view is called UserList.html.view and it extends base.html.twig
The beginning of the file is as following :
{% extends 'base.html.twig' %}
{% block body %}
{% block javascripts %}
<script src="{{ asset('build/js/custom.js') }}"></script>
...
I also tried with Encore by adding an entry but it's not working. The only way to access external functions is to call them from the parent view which is not what I want obviously.
The error I get :
Uncaught ReferenceError: coucou is not defined
at HTMLButtonElement.onclick (VM3883 manageAccounts:183)
onclick # VM3883 manageAccounts:183
I read some other posts about this but none of them actually provided a working solution.
Thank you for your help !
Hello there and welcome to SO forums. It is hard to put a finger on your issue based on the provided pieces of code - but the twig block usage might be something that is not implemented / working as you assume. Namely the javascript block inside the implemented body block has no relevancy to the a similarly named block in base template (I assume that there is similarly named block there) because it is placed inside the body block which you are completely overwriting in this UserList.html.twig template.
A basic working twig structure would be something like this:
base.html.twig
<html>
<head>
...
</head>
<body>
...
{% block body %}
...
{% endblock %}
...
{% block javascripts %}
...
{% endblock %}
...
</body>
</html>
UserList.html.twig - please note the parent() call that makes sure that the block contents from the inherited template are included as well (i.e. if you have some generic jquery or some other generic js includes defined there) - without the parent() you will be defining the javascripts block contents completely again in this template.
{% extends 'base.html.twig' %}
{% block body %}
...
{% endblock %}
{% block javascripts %}
{{ parent() }}
<script src="{{ asset('build/js/custom.js') }}"></script>
{% endblock %}
I hope everyone is doing great during this troubles times ! France started containment last week so I had plenty of time finding the solution.
Dumbest thing ever but I didn't know that..
In your js external files, you have to declare your functions like this :
window.myfunction = function myfonction(){}
That's all..
Could that potentialy cause security issues ? I don't know so I'm asking xD
I have a question about, how to separate a loading specify javascript file of specify template twig file.
I got for example admin.html.twig which extends base.html.twig, in base i got
{% block javascripts %}
<script src="/assets/js/core/jquery.min.js"></script>
<script src="/assets/js/core/popper.min.js"></script>
<script src="/assets/js/core/bootstrap-material-design.min.js"></script>
<script src="/assets/js/plugins/perfect-scrollbar.jquery.min.js"></script>
<script async defer src="https://buttons.github.io/buttons.j"></script>
<script src="/assets/js/plugins/chartist.min.js"></script>
<script src="/assets/js/plugins/bootstrap-notify.js"></script>
<script src="/assets/js/material-dashboard.min.js"></script>
<script src="/assets/demo/jquery.sharrre.js"></script>
<script src="/assets/js/sparkline.js"></script>
<script src="/assets/js/plugins/chartjs.min.js"></script>
{% endblock %}
and I got next file like dashboard.html.twig which extends a admin.html.twig file, and my question is that in dashboard.html.twig file i got at the a little writed-self small javascript code, and this javascript of course use a jquery library but this library i loaded in base.html.twig file a next of my selfwrited script which is in dashboard.html.twig.
My question is, how i can for example load my small code of javascript (of course i can save it in separated file like mycode.js) but how to load only when this route of dashboard.html.twig file i used and after jquery is loaded ? becouse in another routers i dont need this mycode.js so I dont wanna put it to base.html.twig file in javascript block, any idea ?
If dashboard directly extends admin then u can do the following to ensure to load all the admin scripts and to add the dashboard specific script:
{% extends "admin.html.twig" %}
{% block javascripts %}
{{ parent() }} {# execute the parent block, thus loading all scripts in admin #}
<script src="/assets/js/dashboard/mycode.js"></script>
{% endblock %}
You can dived
{% extends "admin.html.twig" %} {# use only in case your all templates are at the same places like app/Resources/views/admin.html.twig #}
{% block javascripts %}
{{ parent() }} {# loads the parent javascript block, from the template you are extending in first line. #}
<script src="/assets/js/dashboard/code.js"></script>
{% endblock %}
in case you are trying to extend a template from another bundle then you can use this
{% extends "YourBundleName:Default:admin.html.twig" %} {# YourControllerRelativeName just in case your view structure is like views/Default/admin.html.twig#}
{% block javascripts %}
{{ parent() }} {# loads the parent javascript block, from the template you are extending in first line. #}
<script src="/assets/js/dashboard/code.js"></script>
{% endblock %}
to the better understanding you should read a little here:
https://symfony.com/doc/2.8/templating.html
Note:- in the documents you should change version as per your current version.
I would suggest the following solution.
Declare the following block in base.html.twig after {% block javascripts %}{% endblock %}
{% block javascript_page %}{# specific code for current page #}{% endblock %}
Then in your page you can include page specific scripts
{% extends "admin.html.twig" %} or {% extends "base.html.twig" %}
{% block javascript_page %}
<script src="/assets/js/pages/my_page.js"></script>
{% endblock %}
Although answer by DarkBee is also correct but in this way you don't have to worry about calling {{ parent() }} in each page.
I've in Django 1.11 a base.html which contains all the scripts references.
Then, I've another page.html that extendes base.html with {% extends base.html %} and {% block content %} / {% endblock content %} tags.
Well. In base.html I've a reference to Chartjs.js plugin. In page.html, if I try to call to Chart() function or just $ jquery, I get "function is not defined". If I open console debugger and try to call $ or just Chart(), it works. So I think that there's a problem with loading time. The page.html is rendered before the js are downloaded or requested!
How can I solve it? I've done it before, I don't know what could be the problem.
Thanks!
Without your code showing, hard to tell. Based on what you wrote, perhaps you forgot to put a block and block.super to get the parent (base.html's) Chartjs reference.
This should be in your page.html at the bottom after your {% endblock content %} tag. See example below (using DataTables as example since your code is not shown):
</div>
{% endblock content %}
{% block javascript %}
{{ block.super }}
<script type="application/javascript">
$(document).ready(function () {
$('#table').DataTable({
responsive: true,
});
});
</script>
{% endblock javascript %}
Base.html would have the js section enclosed in
{% block javascript %} …. {% endblock javascript %}
I am trying to pass my variable from Django's view to a javascript file. I read the stack question here (How can I pass my context variables to a javascript file in Django?) to get a few guidance but I am trying something a little bit different. I want to pass variable to the javascript file within that particular javascript reference script tag or changing the order of variable declaration. It is easier to show by example:
My somerandom.js:
console.log(variable);
What works:
{% extends base.html %}
{% load static %}
{% block body %}
<h1> Hello, World! </h1>
{% endblock body %}
{% block javascript %}
<script>
var variable = {{ my_var }};
</script>
<script src="{% static "app1/bootstrap/js/somerandom.js" %}"></script>
{% endblock javascript %}
What doesn't work:
Edit: It doesn't work because the in developer tool (press F12 in Chrome) I see this error: Uncaught ReferenceError: variable is not defined
1:
{% extends base.html %}
{% load static %}
{% block body %}
<h1> Hello, World! </h1>
{% endblock body %}
{% block javascript %}
<script src="{% static "app1/bootstrap/js/somerandom.js" %}"></script>
<script>
var variable = {{ my_var }};
</script>
{% endblock javascript %}
2:
{% extends base.html %}
{% load static %}
{% block body %}
<h1> Hello, World! </h1>
{% endblock body %}
{% block javascript %}
<script src="{% static "app1/bootstrap/js/somerandom.js" %}">
var variable = {{ my_var }};
</script>
{% endblock javascript %}
Reason I want those 2 to work is so I can organize and refer to my variables properly once my code gets longer. And in this link (http://www.mutaku.com/wp/index.php/2012/03/accessing-django-template-variables-in-javascript/), it shows that we can declare variable after referencing the javascript file.
When you use a <script> tag with a src= ... and a content in it the behavior is undefined, and is strongly related to the browser you're using: for instance with chrome the script is loaded from src=... and the content of the <script> is ignored
However the usage it's strongly discouraged
Enclosing the Django variable in double quotes worked for me. Then you invoke the .js file after the variable declaration.
<script>
var variable = "{{ my_var }}";
</script>
<script type="text/javascript" src="{% static ... %}"></script>
This is because console.log({{ my_var }}) does not print the variable to the console but console.log("{{ my_var }}") does print it.