What's the difference between Partial and Slot in Symfony? - symfony1

The two concepts Partial and Slot seem the same for me. Both of these two features replace placeholders in template with actual markup.
When should I use Partial and when should I use Slot?

The major difference between slots and partials is that the rendering for a given slot resides within a certain template. In opposite, the partial is merely an include of a template into another template.
"Basically, a slot is a placeholder that you can put in any of the view elements (in the layout, a template, or a partial). Filling this placeholder is just like setting a variable. The filling code is stored globally in the response, so you can define it anywhere (in the layout, a template, or a partial). Just make sure to define a slot before including it, and remember that the layout is executed after the template (this is the decoration process), and the partials are executed when they are called in a template."
Examples of ways of using each are:
Title for your page - would probably be placed in a slot (or in the title helper), and you would then in your layout check whether the slot was defined and then show it.
Sidebar items - say you have 3 sidebar "slots", you would then have three slots, for example 'sidebar-1', 'sidebar-2' and 'sidebar-3'. In your template you would then define the slot, which could be rendered using a partial (or even a component) if you wanted.
I hope that clarified it a bit.

A partial comes from a file:
include_partial('thing', $params) will include _thing.php with $params in it's scope.
Slots are not files, but set somewhere else in the template/controller:
slot('title', 'Home Page');
echo '<title>'.slot('title').'</title>'

All you need to know is the Symfony cheat sheet View. Partials, components, slots and component slots (PDF, 45 KB).

You could think of a slot as an OO method definition. Your layout defines slots. The template extends the layout and fills those slots (by overwriting the methods). You can also have a default content for a slot, which is displayed when it's not overwritten.
Partials on the other hand would be like composition. They are a reusable component that templates can access. Roughly they are the equivalent of a simple include statement, but you pass in the variables it uses.
This page does a pretty good job at explaining the concepts: http://www.symfony-project.org/book/1_2/07-Inside-the-View-Layer

Related

How to use "anchor" with associated text (that is not linkable)

From this question (Hyperlink inside label field in Vaadin 12) I was able to use Vaadin's HTML component to create custom html code (and it worked fine, including putting in ahref links etc.)
However, Vaadin provides the "Anchor" component which appears to be the far more powerful (and potentially more secure) way of creating links that can be used to navigate to either other classes I built or to external website (or even to download dynamically generated data in a streaming fashion).
However, what if I want to have both normal "label-like" text and an achor link all appear in a single paragraph? For example, in "normal html", I could just do this:
<p>
This is my normal text.
Download <a href="/resources/excelTemplate.xlsx" download> this Excel file</a>
and follow the instructions therein
</p>
and it would create the link somewhere within my <p>...</p> paragraph. How can I do this in Vaadin with the Anchor object? The best I came up with thus far is to use Horizontal Layout and then add a label, an achor, and then another label -- but that is really really ugly and doesn't technically have the same effect (it won't wrap properly.) The other option is to NOT use "Anchor" but instead just use "HTML" component and just create ahref links everywhere, but that seems a tiny big ugly too (though I suppose it's an ok workaround.). (I'm assuming I can call any UI I build by sticking the url links in the ahref calls....) Thoughts on the "right Java Vaadin" way to do this?
Paragraph p = new Paragraph("para");
Anchor a = new Anchor("go", "www.go.com");
p.add(a);
p.addClickListener(e-> UI.getCurrent().navigate(a.getHref()));
Vaadin 10+ offers you (atleast) three ways to handle this kind of case. You mentioned two of the..
Make composition of components in Java. Instead of VerticalLayout you could wrap the content in Div and using Text component also in Div instead of Label. You can make this kind of custom component by extending Composite.
The second alternative is to use HTML component as you mentioned.
The third alternative is to create custom html polymer template and connect to it with PolymerTemplate class. That will result in custom component that behaves like the custom component of the first option. It is just different way of implementation.
Which one of the three is a correct way. From framework perspective all of them. Which one is correct for you depends on your preference and application.

Applying a master page template in Sling with HTL

Is there any simple way to apply a page template to multiple Apache Sling scripts?
I'm looking for something akin to the JSP 2.0 Tag option. However, I'm using HTL, which doesn't support such tags.
I could, of course, use HTL includes, such as data-sly-include="${'header.html'}, but these would then have to be manually included in every page I then create.
Ideally I'd like to be able to have a master page containing the layout, which is then automatically applied to all pages of specified resource types, leaving a customisable area for content specific to each resource. I'd then be able to limit my add.html, edit.html, html.html (etc) files to include only a block of code for the content section of the page, preventing unnecessary duplication of layout code across multiple files.
I thought I might be able to achieve this by creating a master page resource (e.g. "page"), then setting sling:resourceSuperType on the individual resources but since this acts as a fallback, it'll only kick in if there's no matching script for the sling:resourceType - and there will be such scripts.
You could use a Sling Decorator to wrap your resources so that they always get handled by the common scripts before everything else. This way you can impose the template and include the actual resource to fill in the actual values/blocks/custom scripts.
Another option would be to impose a (nested) content tree where the root points to the template scripts (using JCR type, for example) while the children/content point to the custom scripts (using resource type). This is pretty much what AEM does with cq:Page and its jcr:content.
I ended up using the following approach:
Add a new resource type page
Create a Sightly/HTL template file for the page resource type (/apps/page/html.html); this is the 'master' page template
Include common elements in that template
Within that template, call the 'child' templates by adding the view selector through the following HTL element: <div data-sly-resource="${request.pathInfo # selectors='view', addSelectors=request.requestPathInfo.selectors, requestAttributes=request.requestParameterMap}">
For each sling:resourceType that's to be rendered as a page, add a view subfolder (/apps/example_type/view) and place its HTL templates within that folder (e.g. add.html, html.html)
On each resource that should be rendered with the master template, set sling:resourceSuperType to page
When a request comes in to, for example, /content/example_type_instance.add.html, Sling resolution will therefore try to find a script in /apps/example_type/add.html; there isn't one, so it falls back to the resourceSuperType script in apps/page/html.html, which in turn will use the script in /apps/example_type/view/add.html.
This seems to work for the moment. #Vlad's approach with a Sling ResourceDecorator may be more elegant.

How to keep related Partial page/HtmlHelpers, scripts and css together and not separate references

I have a form that has a button next to person textbox that brings up a person Bootstrap Modal Search Window.
the html I put in a partial page and reference it
#{await Html.RenderPartialAsync("_PersonControlPartialHtml","PersonControl1");}
#{await Html.RenderPartialAsync("_PersonControlPartialHtml","PersonControl2");}
which adds a textbox and button.
Then I add a bootstrap modal html to the page that only has to appear once per page
#{await Html.RenderPartialAsync("_PersonControlModal");}
Then the javascript event code and css for the above.
#section Header {
<script src="~/css/personcontrolscript.css"></script>
}
and
#section Scripts {
<script src="~/js/personcontrolscript.js"></script>
}
The html I could put in an htmlhelper but I still need to add 3 references to the page if I want to add it to a page.
Is there not an easier way?
There are ways to reduce this but those ways come with trade offs. So it really depends on which approach best fits your needs.
So for example you could eliminate adding the .css reference in the header section via two different approaches:
1) you could place those styles in a global.css file that is already loaded for ever page; or
2) you could use inline styles on you html and eliminate these css classes.
Both of these solutions of course have downsides. Approach one means that the size of the global.css styles will be larger and take a bit more time to load even if the first page used on the site doesn't need them. Approach 2 seems to fly in the face of conventional wisdom that you should almost never use inline styles and it will make the markup more verbose. But either solution would allow you to eliminate the need for including a seperate ~/css/personcontrolscript.css reference every time you have a person control on the page.
As for the need to include ~/js/personcontrolscript.js, that could be solved one of two ways:
1) include the javascript code in a global.js file that is loaded for every page; or
2) put that javascript code inline in the _PersonControlPartialHtml and add code to it to make sure that it only gets injected the first time the partial is used on the page.
As for the bootstrapModel, I'm a little less clear on what that code looks like so I can't say for sure but probably it could leverage an approach similar to one mentioned for css or js.
With regard to rendering your partials, I don't think there is any way to eliminate that given that it's the primary representation of the functionality you are adding to the page.

Change CSS style using drop down menu in MVC

I'm trying to make a drop down menu that has a bunch of items (Amelia, Cerulean, Cosmo, Cyborg, Flatly, Journal). Each of these items represent a css file.
When one of them is selected I want my website to take this selected css file and apply it to the website.
I would like the drop down menu to interact with jquery, meaning when a item is selected jquery takes over and makes a asyn/ajax call to some mvc actionresult.
By the way I'm using MVC 5.
I hope someone can help me sketch the initial groundwork.
I've implemented this in my application.
I'm not sure what to tell you though. It's easier when we have an attempted solution to fix.
Here's an overview of how mine works:
I have created a controller called SharedController. The purpose of it is to contain various actions that render common actions. All of the actions are considered ChildActionOnly.
My _Layout uses RenderAction to render the action NavbarPartial which is in my SharedController.
More importantly the Navbar partial then uses RenderAction to render the action ThemeListPartial. This action is responsible for getting a list of available themes. The list of available themes is determined at applications startup. I've created a ThemeFinder class and ThemeRepository class that are responsible for finding and storing themes. The ThemeFinder finds themes by expressions that you give it. In a new class called App_Start/ThemeConfig I've given it only one expression - "~/Content/themes/{name}.bootstrap.css". This will find all themes with that naming convention in that location.
My razor code will take the ViewModel and display a dropdown menu in the navbar.
To get the themes to change my dropdown menu contains an AJAX link to an action called SaveTheme in ThemeController. This action takes a theme name as a string and tries to save it in a cookie for the user.
If the theme is found and saved successfully, the action responds with a success message.
jQuery then changes the theme by finding the associated link attribute and changing the HREF contents to the new theme. It knows the new theme relative URL because I have it stored in data attributes.
I completed this before I made the switch to AngularJs. The one thing I plan to go back and change is to cut out as much (maybe all) jQuery as possible and replace it with better code.

ROR: Nested views

I have a page object and various template objects in my application. pages have names, descriptions urls etc and each have a relationship with a template. templates have different numbers of content boxes and relationships with other controllers (like blogs, galleries etc.).
When I am rendering a page I can work out what template is attached to the page, and what the relevant content is based on that. but I am not sure what the best way is to render the nested Items.
Are you meant to somehow render the templates view from within the other view? Or would you have to just rewrite the view altogether? In this case would I have to create an extra template view for each different template, bundle it with the page views, and then only include it if it is the right one?
Would this be the same for galleries and blogs? do they all need to be bundled with the page? Or can it be called from its proper location?
I'm not sure what the best practice is here and haven't had any luck googling it. I'm suspecting that the key words im using aren't correct. Or this is common knowledge that isn't worth documenting.
You can use shared partials to render views. Check out this guide.
In the views, you can render the partials based upon whatever condition you want.
For example:
- if params[:page] == "my_page"
= render "shared/my_page"
Naturally, you will still need to set up the needed data in the controller.
Shared logic for this can be placed in the Application Controller.

Resources