Reputation: 1065
The following code is in my Twig
template and it's for load a CSS
file or another depending on the theme selected by the user. This works perfectly on a simple HTML
page but when I try to take this to the Twig
template of my Symfony
application I can't find a way to pass the CSS
route (with Twig
) to the Javascript
document.write
function.
<script>
var themeSettings = (localStorage.getItem('themeSettings')) ? JSON.parse(localStorage.getItem('themeSettings')) :
{};
var themeName = themeSettings.themeName || '';
if (themeName)
{
document.write('<link rel="stylesheet" id="theme-style" href="css/app-' + themeName + '.css">');
}
else
{
document.write('<link rel="stylesheet" id="theme-style" href="css/app.css">');
}
In other words: I want to put in the href
of the document.write
function what (in Twig
) it would be this:
<link href="{{ asset('bundles/activos/css/app-red.css') }} "rel="stylesheet" >
Where "app-" is invariable and the word "red" is variable depending on the value of the var themeName
For that I've try this:
<script>
var themeSettings = (localStorage.getItem('themeSettings')) ? JSON.parse(localStorage.getItem('themeSettings')) :
{};
var themeName = themeSettings.themeName || '';
if (themeName)
{
document.write('<link rel="stylesheet" id="theme-style" href="{{ asset('bundles/activos/css/app-' ~ themeName ~ '.css') }} ">');
}
else
{
document.write('<link rel="stylesheet" id="theme-style" href="{{ asset('bundles/activos/css/app.css') }} ">');
}
</script>
But it doesn't work, It gave me this error:
Variable "themeName" does not exist in ::base.html.twig at line 1188
I guess it's because themeName
is not a Twig
variable but a Javascript
variable.
I think that the problem here is that I can't pass a Javascript
variable to Twig
because Javascript
is client-side
and Twig
is server-side
.
So, how can I solve this problem? Maybe I'm going through the wrong way, maybe using Ajax
can be an option, but I don't know how to do it.
Upvotes: 2
Views: 5523
Reputation: 9
Strange, the author asked Javascript to be transferred to Twig, but in fact he wanted Twig to be transferred to Javascript? For me it works like this
<script>
{% set twigVar = 'jsVar' %}
</script>
Upvotes: -1
Reputation: 15590
As you can't pass a javascript variable to twig you will need to fetch the theme uri by ajax.
<!DOCTYPE html>
<html>
<head>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<link rel="stylesheet" id="theme-style" href="{{ asset('bundles/activos/css/app.css') }}">
</head>
<body>
<script>
$(function() {
var themeSettings = (localStorage.getItem('themeSettings')) ? JSON.parse(localStorage.getItem('themeSettings'))
: {};
var themeName = themeSettings.themeName || '';
if (themeName) {
$.ajax({
url : "url/to/get/theme_uri.php",
type: "POST",
data : {
'themeName' : themeName,
},
success: function(data, textStatus, jqXHR)
{
$('#theme-style').attr('href', data.uri);
},
});
}
});
</script>
</body>
<?php
//... This would be a symfony controller
public function themeUriAction(Request $request){
$path = 'bundles/activos/css/app-' . $request->request->get('themeName').'.css';
return new JsonResponse(array('uri' => $this->container->get('templating.helper.assets')->getUrl($path)));
}
//...
If you know all the themes at front, you can add them into an array, then you don't need to use ajax
<!DOCTYPE html>
<html>
<head>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<link rel="stylesheet" id="theme-style" href="{{ asset('bundles/activos/css/app.css') }}">
</head>
<body>
<script>
var themes = {
{% for theme in themes %}
'{{ theme }}': '{{ asset('bundles/activos/css/app-'~theme~'.css') }}',
{% endfor %}
};
$(function() {
var themeSettings = (localStorage.getItem('themeSettings')) ? JSON.parse(localStorage.getItem('themeSettings'))
: {};
var themeName = themeSettings.themeName || '';
if (themeName in themes) {
$('#theme-style').attr('href', themes[themeName]);
};
});
</script>
</body>
</html>
Upvotes: 1
Reputation: 2137
To concat in javascript you have to use '+
' operator
'~
' operator is for twig concatenation
document.write('<link rel="stylesheet" id="theme-style" href="{{ asset('bundles/activos/css/app-' + themeName + '.css') }} ">');
Upvotes: 1