I try to generate a way that I will be able to get the URLs of each AJAX call by using Twig's path function. The reason I am doing that is because I try to create a single-page application by using Knockout MVVM and require.js therefore I need Ajax calls and I need the URLs to be generated dynamically.
The way I do it is that I create a Route:
/**
*@Route("/ajax.js",name="ajax_calls")
*/
public function ajax_calls(Request $request)
{
$response=$this->render('javascript/ajax_calls.js.twig');
$response->headers->set('Content-Type', 'application/javascript');
return $response;
}
And I load the specific template (javascript/ajax_calls.js.twig):
/**
*Returns the urls of the calls we need
*/
define([],function($)
{
return {
/**
*Urls for the albums (aka image groups)
*/
'albums':{
'get':function()
{
return "{{path('user_groups')}}";
},
'add':function()
{
return "{{path('group_add')}}";
}
'delete':function()
{
return "{{path('group_delete')}}";
}
'edit':function()
{
return "{{path('group_update')}}";
}
},
/**
*Urls for the Images
*/
'images':{
'add':function(group_id)
{
return "{{path('add_images', group_id='^group_id^')}}".replace("^group_id^",group_id);
},
'delete':function()
{
return "{{path('delete_images')}}";
}
}
};
});
I use fefine because I want to be able to be loaded with require.js and as you can see I try to generate an Object that returns the URLs for a specific part of an single page application.
But somehow on line:
'albums':{
There's is a conflict and I do not know how to escape it.
The specific error I get is:
Arguments must be separated by a comma. Unexpected token "punctuation" of value ":" ("punctuation" expected with value ",") in main.js.twig at line 11.
How can I fix this, or is there an alternative way to get the URLs as a JavaScript object (by generating them dynamically)?
Note: I also seen the https://github.com/FriendsOfSymfony/FOSJsRoutingBundle/blob/master/Resources/doc/index.md as posted on Ajax url parametetr using Twig path
But it does not help me on how I designed the application (I use view models and I want to keep the view models as clear as possible from URLs and load them externally).
Also I will be grad for an alternate way to do that.
I tried with:
/**
*Returns the urls of the calls we need
*/
define([],function($)
{
return {
/**
*Urls for the albums (aka image groups)
*/
'albums': {% verbatim %} { {% endverbatim %}
'get':function()
{% verbatim %} { {% endverbatim %}
return "{{path('user_groups')}}";
},
'add':function()
{% verbatim %} { {% endverbatim %}
return "{{path('group_add')}}";
}
'delete':function()
{% verbatim %} { {% endverbatim %}
return "{{path('group_delete')}}";
}
'edit':function()
{% verbatim %} { {% endverbatim %}
return "{{path('group_update')}}";
}
},
/**
*Urls for the Images
*/
'images': {% verbatim %} { {% endverbatim %}
'add':function(group_id)
{% verbatim %} { {% endverbatim %}
return "{{path('add_images', group_id='^group_id^')}}".replace("^group_id^",group_id);
},
'delete':function()
{% verbatim %} { {% endverbatim %}
return "{{path('delete_images')}}";
}
}
};
});
And returns the error:
Arguments must be separated by a comma. Unexpected token "punctuation" of value ":" ("punctuation" expected with value ",") in main.js.twig at line 11.
I also get the same error with:
{% verbatim %}
/**
*Returns the urls of the calls we need
*/
define([],function($)
{
return {
/**
*Urls for the albums (aka image groups)
*/
'albums':{
{% endverbatim %}
'get':function()
{
return "{{path('user_groups')}}";
},
'add':function()
{
return "{{path('group_add')}}";
}
'delete':function()
{
return "{{path('group_delete')}}";
}
'edit':function()
{
return "{{path('group_update')}}";
}
{% verbatim %}
},
/**
*Urls for the Images
*/
'images':{
{% endverbatim %}
'add':function(group_id)
{
return "{{path('add_images', group_id='^group_id^')}}".replace("^group_id^",group_id);
},
'delete':function()
{
return "{{path('delete_images')}}";
}
{% verbatim %}
}
};
});
{% endverbatim %}
I figured out that I generate an another JavaScript file. The controller generates it by using the main.js.twig:
requirejs.config({
baseUrl:'{{asset('')}}',
paths:{
'text':'assets/vendor/js/text.min',
'knockout':["https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.0/knockout-min",'assets/vendor/js/knockout.min'],
'pager':"{{asset('assets/vendor/js/pager.min')}}",
'jquery':"{{asset('assets/vendor/js/jquery.min')}}",
'boostrap':"{{asset('assets/vendor/js/bootstrap.min')}}",
'ajax':"{{path('ajax_calls')|replace('.js':'')}}",
{% block Viewmodels %}
{% endblock %}
'compMessage':'assets/js/components/message',
'extBooleanToggle':'assets/js/extenders/booleanToggle',
},
shim:{
'pager':['knockout'],
'bootstrap':['jquery'],
},
waitSeconds: 200,
});
{% block initFunction %}
{% endblock %}
And the problem that generates is the line:
'ajax':"{{path('ajax_calls')|replace('.js':'')}}",
What I try to do in this line is to generate a "fake" .js file without the .js in order to require.js to load it with .js extension.
I changed the line:
'ajax':"{{path('ajax_calls')|replace('.js':'')}}",
with:
'ajax':"{{path('ajax_calls')|trim('.js')}}",
On main.js.twig and works like charm!