I would like to know how was it possible to insert code from Backbone / Underscore function in twig?
Here is my problem:
{{path('getArticle', {"id": <%= id %>})}}
I need to change this variable : <%= id %>
This does not work because Twig Parse before the Backbone code. So I do not know how to give a variable of this type?
Thank you in advance
I suppose you are using Symfony in the server side, along with TWIG.
In that case, you just have to send the $id variable to your TWIG template
public function callMyTwigAction($deskId)
{
$id=whatIwant();
return array('id' => $id);
}
and then just call in your TWIG file :
{{path('getArticle', {"id": id})}}
It looks like you are mismatching client template and server template.
A client template like Underscore Template (or rather use Mustache) is transforming raw web services data (JSON or XML) into HTML and is (probably) written in Javascript.
Server side template usually transforms business objects (Java/PHP classes) into HTML and uses an engine such as TWIG or Velocity.
With the more complicated architecture I would propose three things :
simplify your architecture :) Something is perhaps wrong.
Make a web service to get the path of a given id (but this would make the architecture even more complex)
create an array of paths with Twig in your javascript. Thiw may be ok if there is less than 200 articles and if this page is not too often displayed.
Do you use TWIG in the server side ? What technology stack do you use ?
Use FOSJSRoutingBundle. It generates a map of all your exposed TWIG routes, which you can then use in your Javascript.
Making the Routing component global, or inject it into your underscore template. Then simply call it similarly to how you would do it in TWIG, but with a JS notation:
Get Article <%= id %>
Related
I'm a newbie and this is my first question so please be nice with me :)
In my Symfony 2 project I want to pass an $user object from my controller to the twig template. This object contains all relevant Information (like username, activepage ...) for rendering the view. My problem is that I would also like to put the result of mysqli database query inside the object. To be able to retrieve it in my twig template, I need two serialize the result object(array?) in the controller before passing. Unfortunately I dont know a way how to deserialize that object in twig( no twig filter available).
My questions:
Is this actually an elegant way or should i rather pass all objects in an array to the template?
Would it work to write a deserialize function inside the user class, which i can call in the twig template?
Will performance be ok?
How do the experienced people do this?
Thx for helping!
Built an array with your data in your controller and render it like this to your template :
return $this->render('yourbundle:example:index.html.twig', array(
'myArray' => $array,
Then in your template you have access to myArray like this :
{% for data in myArray %}
...
{% endfor %}
I made a service such a parameter bag which I can add parameters/values along the process, and render every parameters with twig so I can use them in javascript.
For that I had to use mostly JsonSerializable php interface (PHP 5.4+), and json_decode twig filter.
I think it is a nice way to pass variables to js like this because you can use this service when building your project.
I currently am trying to make a variable using the current url for the view. To get the url, I am using {% set uri = app.request.uri %} (uri being my variable which is the current url for that particular view). The thing is, I am only interested in what makes the url unique (the end of it - a unique object from an array - happens to be a uri), and not the beginning (path to my application). I was thinking I could use a preg_replace to do so, but TWIG doesn't have this function. Just wondering if someone would know how to accomplish what I am trying to do?
I'm new to Symfony (and fairly new to PHP), so my explanations may not be clear (sorry).
Ex.
{% set uri = app.request.uri %}
output: http://website.com/http://item.org/1
I want to modify the uri variable to ONLY have http://item.org/1 (and not the path to my website).
I'm thinking creating a Twig Extension with the preg_replace will allow me to do this ..but not sure if it's the best way to go (inexperienced).
Overall goal:
The unique value for "uri" in the view is appended to the websites path by another view from an array of objects ($results) with attributes, one being "uri". My ultimate goal is to only display all associated attributes (or row) for an object in my $results array. I was thinking I could do this by first creating a key (my uri variable) in a foreach, and returning the row in the array which matches this key. This is why I am trying to create a variable with the url so that I can use it as a key for my foreach loop to iterate over $results. I am NOT using a database or Doctrine.
Thank you ahead of time for the help!
The best way is to move the logic from template to the controller.
If you need preg_replace in twig you must create custom extension.
Someone seems to have created a Twig Extension for preg_replace, see https://github.com/victor-in/Craft-TwigPCRE
You can do it like that. It's a bit ugly but it works.
uri|split('base_path')|join('')
Can i create helper function like codeigniter in symfony2?
I want one function which should print array inside pre tag like
public function print_in_pre_tag($array) {
echo "<pre>";
print_r($array);
echo "</pre>";
}
I often print array like in that format to check the values.
Please suggest some solution and let me know where can i keep the function?
Edit 1: If i call like print_in_pre_tag($array); inside any controller
above function should invoke.
You should create a service (helper in codeIgniter) for that.
Create a folder called Services in your bundle. Create a file in that folder called "PrintManager.php" (or however you want to call it - but make sure the first is capital)
Then inside PrintManager.php you put:
namespace Company\MyBundle\Services;
class PrintManager {
public function print_in_pre_tag($array) {
echo "<pre>";
print_r($array);
echo "</pre>";
} }
Then in your services.yml you set the file:
parameters:
print_manager.class: Company\MyBundle\Services\PrintManager (notice, no .php extension)
services:
print_manager:
class: "%print_manager.class%"
And then in your controller you can just call it like this:
$printManager = $this->get('print_manager');
$printManager->print_in_pre_tag($array);
Btw the best thing you can do is let your service handle the functional part and let it return the result to your controller and from there you work with the results.
like: $text = $printManager->print_in_pre_tag($array);
Actually, I do not understand why people recommend Services.
Services have to contains business logic.
For you task use Helpers. They are static, and you do not need instance!
You should use the LadybugBundle which exactly does what you want. It's much more easier to use as you can debug with calls like:
ld($array);
ldd($array);
Moreover, those helpers are available anywhere in your PHP code without requesting or defining a service. Finally it also works to debug in the console, Ajax calls, Twig templates...
Actually, the question is too old to answer, and actually my answer is not about a Helper, it is about the function that you need. You need a pretty var_dump().
From Symfony 2.6, we have the VarDumper Component. You can use it wherever you need, whenever you need, in your php code, of course.
You have to use the function dump(). You can see the dump in the Developer Bar, and also in a redirection page. The output of the dump, it is better formated, because you have arrows to expand all the inners arrays.
Just to let you know guys
I am having issues with twig escaping output on method calls to an object passed into my twig template. I know I can get around this with the |raw filter, but was hoping there might be a way I could simply specify in my object that certain methods are safe and therefore remove the need for the raw filter.
Method calls of objects itself cannot be made html safe because normal objects/entities are not (and should not be) aware of the template engine.
However, a twig filter or function if aware of the template engine and can be marked html safe in its definition.
So what you need to do is to implement a html safe twig filter to pass the object to and call the method of your object inside the filter function.
I guess your templates looks like this:
<p>{{myObj.getHtmlRepresentation()|raw}}</p>
Now you need to implement a twig filter and change the template to the following:
<p>{{myObj|html_representation}}</p>
And the twig extension should look like this:
class MyTwigExtension {
public function getFilters(){
return array(
// the magic is the is_safe=>html option
'html_representation' => new \Twig_Filter_Method($this,'htmlRepresentation',array('is_safe'=>array('html'))),
}
public function htmlRepresentation($obj){
return $obj->getHtmlRepresentation();
}
}
One design consideration: If your object is an entity of a business object of some kind, it sould not create html but you should move the html creation to a template or the twig filter..
I need to get some Json to the client side from the server and it's somewhat troublesome as almost all tutorials assume an Ajax call to a separate action to get the Json.
This led me to think that there must be some reason why it is done this way. In Asp.Net MVC we can pass a Model along with the view to get the information but we can't seem to easily pass a Json object. Instead you are supposed to make a separate call to get this information.
What if the Json info is known when the page is generated, why not generate it at the same time?
I'm sorry if I wasn't clear enough. While it's nice to hear of ways to get Json to the client, the question is actually whether there is a specific reason the Ajax call method is much more popular, like security or anything like that.
Can you put something like this into your view? (rough pseudo code, assuming using a Razor view)
< script >
var myJSON = { Field: #model.Field, Field2: #model.Field2 };
< /script >
Because you do not need both at the same time... on the first call will be to get html (the view of the data - represented by a view model), and any ajax calls will be to get the possibly updated data (json serialized view model).
No reason why you can't. You could use the javacript serializer to create a JSON string that drop on the page. You could also create an action that return the json string that you called from a script tag.
What you want if you're using KnockOut, would be the Mapping plugin that turns an ordinary JS object, like that generated above, into an observable ready for KnockOut to use. See here from info. http://knockoutjs.com/documentation/plugins-mapping.html
You can use content-negotiation by setting accept header. This is considered a best practice (and according to some RESTful).
This needs to be supported and implemented at server as well. ASP NET MVC does not make it easy to support content-negotiation and you have to implement it yourself by if-else or using ActionFilter and implementing action selector.