why does twig's render function create a subrequest - symfony

why does twig's render function create a subrequest ? Why dont they just render the response and send it as part of the response ?
Also I can see that the rendered response appears in the browser just after the main template shows up. How does it happen ?

I created an answer on Stackoverflow which basically goes through the different alternatives of the render function.
It also explains why you should be using the render function over a regular include.
I'd advise you to read the chapter about embedding controllers in Twig. An interesting quote from the doc about when you should consider using the render function:
Whenever you find that you need a variable or a piece of information that you don't have access to in a template, consider rendering a controller.
TL;DR
By default, the render function only takes a URL (either absolute or relative).
By analogy it is like getting HTML through ajax and injecting it in the page: one request that queries a controller to get some HTML which get injected it into the page.
There are different render calls like render_esi (for support of the ESI tags) that have their own rendering strategies. If you start with the inline rendering (through the default render function) you will have the opportunity later on to use other rendering strategies without refactoring your code.
The render function is meant to scale your application.
For more details about its usefulness, let's look at the render_esi function.
With the render_esi function you can implement ESI tags to use with Varnish.
(There are other solutions than Varnish but it's among the most popular ones)
Varnish is a caching solution that is located between your web servers and the users. Varnish will filter the response from your web servers, cache the entire page then look for these ESI tags.
If Varnish cached your page for a day but the render_esi function are set to be cached for 2 hours, Varnish will only query (through a URL when the cache expired) for these specific render calls instead of the entire page (which is why render_esi do sub-requests) and replace parts of the template with the sub-requests' response.
Caching in general is very interesting and very broad so it's hard to go over every details in my answer but I hope my answer will help you.
Caching (or cache) according to Wikipedia:
In computer science, a cache (/ˈkæʃ/ kash)[1] is a component that transparently stores data so that future requests for that data can be served faster.

Render is used when you not just want to include another template snippet, but also want to execute specific businesslogic, that belongs to this template. Or in other words: When include just isn't enough, you use render.
Because render doesn't only include a template, but also executes controller logic, it is encapsuled as a subrequest.
Imagine you want to display the latest news in a box on every page of your website. If you want to solve this with an include, you would have to fetch the latest news in each of your actions and pass it to your template.
But if you use render, you just write one action for this, and put a render tag everywhere in your templates where you would like to have that news box. The render tag executes the associated controller action, renders the response, and injects it into your current template.
Because I suck at explaining, you might also want to read this part of the symfony doc: http://symfony.com/doc/current/book/templating.html#embedding-controllers

In my opinion, answer should sound like this:
Controller is pretty simple "unit" which receives request and sends response.
Creating sub request for rendering controller gives you more power (flexibility).
About flexibility. Look at your controller, just like it just receives request and sends response and for example, you want to somehow filter request or decorate response? Where will you put this logic? Of course, at event listeners which can use other services to solve this task.
For example, I often use parameter converters for my controllers (it's not about good design, just for example). So how can I use "render", with specifying just id of my entity, to render only controller without creating sub request?
If you really want just to render some data you can use "include" or create an extension. Or you can create extension to render controllers without sub request, but think about it carefully, because further you can add more logic to filtering response and so on.
I can be wrong, it's just my opinion ;)

Related

Convert query parameters to "pretty urls"

I have an Episerver site with a JobDetailsPageController with a Index method that takes a jobId parameter and creates a view with some details about that job. The urls looks something like this: https://hostname/<root-depending-on-site-tree>/jobs/?jobid=44.
What I would like is having urls on the form .../jobs/manager-position-telco-44, essentiallly creating a slug of the job title and appending the id. I have done this in the past using standard ASP.NET MVC Attribute Routing on a non-Episerver site, but EpiServer has a routing of its own that I don't know too well and can't figure out.
Also, adding non-query strings after the slash consistently sends me (no surprise) to a 404 page, so I would need to somehow customise this behaviour. I need to use EpiServers standard routing to end up at the right "parent", but ignore the latter part (the pretty bit).
Is it possible to create such urls on a normal page in page tree in EpiServer? I do understand it is possible to create static routes, but this node can be moved around like any other page so I cannot avoid EpiServer.
Please see this blog post. What you're looking for is partial routing.
#johan is right, partial routing is one way of doing this. Just wanted to add other possible solutions that might or might not match your needs.
Import data as content
Instead of serving content dynamically, you could consider importing your job ads from whatever source you have directly in content tree as separate pages below particular root page. That would give you a lot benefits - pages would be cached, it would support multiple languages, editors would see content directly in EPiServer CMS, data could be adjusted manually, etc.
This would be a good solution if your data does not change often and you need to provide a way for editor to create a new job ad manually as well.
Implement you own content provider
Another way to serve your dynamic data to EPiServer is to write your own custom content provider. You can find documentation here: http://world.episerver.com/documentation/Items/Developers-Guide/Episerver-CMS/7/Content-Providers/Content-Providers/
This solution requires more coding and is more complex, but it has some benefits as well. If one wanted, it would be possible to not just serve content from external data source, but also update that data by changing values directly in EPiServer UI.

Does ASP.NET have an extension point through which all URL generation code is passed?

I am looking for a way to alter URLs generated by calls to on the many methods on UrlHelper or Control.ResolveUrl() in a way that is completely transparent for the developer.
The main scenario is adding a language 'tag' to URLs. The developer creates a link to an action or to an ASPX page as usual, but the URL generation is 'intercepted' to make the link 'language aware' so to speak. I would prefer not to see this cross-cutting concern 'leak' into the code. (When the user clicks the link, the language tag in the URL is interpreted, and the request is rewritten, so it 'just works'.)
Does ASP.NET have the required extension point to do this? In other words: what kind of class can I register (and where do I register it) that is called always when a URL is generated?
A cursory glance at the source code at aspnetwebstack.codeplex.com indicates that ASP.NET ultimately relies on the VirtualPathUtility class, but unlike the VirtualPathProvider (used to resolve incoming URLs to files on disk) it cannot be implemented (it's a static class).
Its nasty but you could register a http module which greps/string replaces your URLs in your responses with what you need. This would involve using a series of regexes to get at the html emitted and swapping out with what you need, which would be even easier if you could have a placeholder in the URL to begin with.
Other than that writing your own bespoke methods and then doing find and replace with their counterparts wouldn't be too onerous.
Maybe even AOP might be useful if you could mark the method where you wanted to do your replacement and could get instance data into it (not sure this is a starter)
Or how about custom attributes, which could be enumerated on a page and have the instance of the page passed in for more fine grained control (similar to the way domain object validators might work) whereby controls housing the offending URLs could be accessed and rigged.

Symfony2, how create a widget like a standalone class

Let's start with basic thing, simple example is Yii. It has such thing as widgets. Standalone, configurable and callable from any place we want classes. And I'm wondering can symfony2 has the same? What it will be? Controller in bundle? Action simple (method)? Widget (twig) with parameters?
In Yii we create class (of widget), standalone, describe it and use (by calling in template). How will it look like in symfony2?
Simple example 'i want create menu navigation using widget, where it will construct html by user roles'.
Symfony doesn't provide such a feature however you can make them yourself. They are few ways of doing it.
I'll just admit that we are talking about widgets that could do backend work (i.e. get data from DB, call an API, etc.).
1 - The scalable way
The use of the render tag in Twig which allows you to call a controller action from a template. It's scalable because you could use esi tags with Varnish (you can also implement your own caching profiles).
As a bonus, the profiler will show details about the specific render calls in the timeline (it will look like a subset of the entire request).
2 - Include a template
The included template gathers the data through a Twig function call. By experience, it's a bit faster than the first solution however it's not easily scalable.
3 - Render through a custom TwigExtension
The twig function will get the data and call the renderView method of the template service. If you are planning on doing this, you probably want to use the first method.
Conclusion
If you have a big website with modules/widgets that gets a lot of traffic (or "hit"): use the first solution.
If you have a small website with no support for caching: use the second solution. You'd use this solution if the module/widget is super light.
If you are thinking about the third solution... it's probably a good idea to use the first solution.
Personally, I'll always try to use the first solution and try to boost the performance one way or another. The render call in Twig has been significantly improved since the last versions of Symfony2.
Hopefully, my answer will provide you some guidelines.

Creating a Website Widget / API

I recently created a website for a friend (asp.net/sql server), the website includes news of his company and he and his team update this frequently.
The question has been asked if i could now create a widget / api of some sort that visitors of the website could now include the news on there own website should they wish too. I feel this needs to be a one line of code intergration or something that is extremely easy to intergrate.
Any recommendations or articles are welcome.
EDIT: how is something like this created
http://img830.imageshack.us/img830/7769/codingabandwebsitecreat.png
Thanks
With jQuery's ajax and an asp.net handler that returns an injectable html chunk is my off hand guess at simple way. Other's will probably know of frameworks if you don't want to roll your own. Is RSS to primitive?
you could also write a REST service in WCF since you're using asp.net and have it return XML or JSON, depending on how you write your widget.
How something like that is created... Well, I've created a number of these and the process is fairly simple. Sorry I don't have an article to reference. Create a 'widget creation/builder' page with input parameters, when submitted either store those in the database and return an ID to associate with those settings, or generate a list of param's for those settings, or both. Simply output the <script> tag into a textbox. Like so (inside an AJAX callback):
$("#results").html("<script type='text/javascript' src='" + widget_path + params + "'></script>");
Where widget_path is the absolute path to the widget ASP script, and params is either something like key=454 or theme=sunny&source=34&count=50 etc. Either manually or using something like jQuery.param to serialize the form. An alternative would be two <script> tags with settings in the 2nd and calling a widget initialize function.
They can copy and paste that into their site, and that ASP script should output only JavaScript, which you can either document.write() or use a JS library (such as jQuery) to operate on the DOM (.click() etc). If using a database the ASP script would check the key param and grab the widget settings, if not then simply process the params. It's important to mention if you want to communicate back and forth with an API, you need cross-domain enabled or you could simply use JSON (in ASP script check for a 'callback' parameter, wrap JSON in that function name, and use jQuery.getJSON with &callback=? at the end); there are other methods of course.
If you use a database, make sure to take security into account (SQL injection, etc.)
WidgetBox looks like a good, mainline method as well.

Component controller in Spring-MVC

I am designing a web application that requires loading multiple components on a single page. (In terms of page layout is similar to Google reader) I like to keep these components separate from each other (for reasons such as reusability). For example, I have a left panel that let's user navigate among multiple feeds that he's subscribed to (user specific) and on the right side of that we show the contents of that feed, and maybe a right panel which shows some specific info about that specific feed.
My understanding of MVC and more specifically Spring-MVC is that each controller is in charge of the entire page. Here are 2 solutions that I have came up with after researching this a bit, and none of them sounds good to me.
Have a main controller that is mapped to that URL, and then load the other components from inside the jsp file. This is doable but doesn't sound like a good solution.
Using portlets.
I want to know what are the best practices. This sounds like a very common web design issue in MVC frameworks, how do people do it?
Spring MVC controller is usually "in charge" :-) of handling a particular request which does not necessarily mean that said request results in a monolithic page being presented to user.
Since you're talking about Google Reader-like functionality, perhaps you'll be using AJAX to load / navigate between different components on your page? If that's the case, you can easily map your 3 components to separate controllers (via separate URIs) plus have one "main" controller to initially load the entire page.
If that's not the case and your page is static, you can have your controller act as "router" of sorts by first instantiating your components and then directing commands / requests to an appropriate component as necessary. Each component would update its own part of the model after which your "main" controller would return the view to be rendered.
Can you use portlets for this? Sure. But if we're talking about a single page it might be a tad overkill.

Resources