Perhaps it was my wording when searching because I new to Laravel but I am trying to figure out the most feasible way to create a user defined header script variable. My thought behind this is to be able to have an auth section of the website - /header and on that route I would be able to manage a section of the header where I can add Analytics script or any 3rd party script tag.
Thought is to include #yield('userHeader') in my master template.
Then in each page it should be included in just add a section
#section('userHeader')
{!! $header->script !!}
#endsection
So I would essentially have to create a model for Header and a new DB table to house the entirety of the script tag.
Seems like it would work but I'm sure someone has done this before. Is there a more efficient way of doing this?
If I do decide to do it like stated above I would essentially then have to:
use App\Header;
in each controller I would want
$header = Header::all();
Then use the following in each page. There should only be a single record in this table because there will ony be one user defined header so I am not sure that a DB table is necessary. Is this the best way to include a user defined area in the header? Will it cause any issues with security or site stability if this will include special characters?
#section('userHeader')
#if(count($header) > 0)
{!! $header->script !!}
#endif
#endsection
You can do it with View Composers
Or you can set the data in the Main Controller and access it from every controller which extends the main one. I think it will be better with View Composers
Related
I've recently started creating a layout template for my Laravel project following the method stated on here:
https://selftaughtcoders.com/from-idea-to-launch/lesson-20/creating-a-laravel-5-blade-layout-to-standardize-your-pages-appearance/
It seems easy enough to wrap a view with a 'master' layout. However, my layout includes a userbar in the top right (kind of like SO's) which has the user's avatar and username.
What is the best way to do this? I can't imagine I have to pass it through to every view that extends my master layout, but at the moment, it seems that is the only answer.
In your master layout you can simply add the user bar and wrap it in the blade helper #auth like this
#auth
This will only be shown when a user is logged in.
#endauth
Check the control structures from the documentation for more detailed information.
I think you will first need to add an separate element in some element folder. This could be the first step to perform.
Secondly, once you are done with the first step, you will also have to extend the element with #extends() function in main layout.
I hope this helps.
Bit of a beginner question about Symfony2/3 here.
Say I'm building a page to display an article. I create a route like "/articles/{id}", link that to a controller which queries the database for the relevant article dataset and pass that on to a Twig view template to display everything. So far, so simple.
But what if I wanted to also include a "Related posts" section at the bottom of the page, which presents other articles with similar topics that might also be of interest. Or a sidebar with numerous other widgets that all require their own logic and database queries.
So, how do I go about supplying every element of the final page with the required data? Do I anticipate every single element of the view and query the data that will be needed beforehand in the controller, to hand it over in bulk? (But if so, what if I modified my sidebar template and switched the widgets around. Would I then have to update the logic in every controller on my site that leads to a page with the sidebar?) Or do I just somehow call back additional data from inside the view when needed?
Coming from simpler stuff like Wordpress where the logic is freely mixed within the view and PHP functions can be called whenever, the seemingly strict and/or desired separation between the view and the logic is introducing a new data flow I'm still trying to wrap my head around. Thanks!
I Hope You can achieve this by embedding Controllers in a Template:
<div id="sidebar">
{{ render(controller(
'AppBundle:Article:recentArticles',
{ 'max': 3 }
)) }}
</div>
Refer : https://symfony.com/doc/current/templating/embedding_controllers.html
I am wondering if there are any way in laravel to send a variable to the layout master and keep it there while the user is logged in. I know how I can do it, like this
$this->layout->with('catalog.categories', $data);
But the problem of this is that I will have to be sending the variable on all the controllers and through all the class. And to get the variable I will need seven or eight lines of code on top of that.
I will give you an easy example. Imagine I have a messenger center in my web. And I want to show the user all the messages he did not read on the top bar. It has to be on the layout master and stay there until he read the messages. Do I have to pass this variable every single time the user changes the route?
Laravel has a nice way to handle issues where a same data is used in all views. View Composer is what you are looking for.
View::composer(array('view1','view2'), function($view)
{
$view->with('data', 'value');
});
Now data varaible is bound to view1 and view2. That means they it will be available every time you load these views.
Where to place them? You can place your view composers wherever you want as long as Laravel can identify it.
Read docs: View Composer
I have a blade template called 'main' and I wonder how I can render a sub template by calling a controllers method in my main template. Lets say I have a Controller WidgetsController with a method getSubView. The method returns a specific view with some data from (for instance) a database.
I already tried to #include a template but this will not call the controller which sets some necessary data to the view.
Thanks.
views don't call services, they only take variables and put them on screen for presentation.
you're on the good side with #include(). you only need to gather the infos for that sub view beforehand in the controller, and pass it to the View::make('main')->with($vars).
you may also consider using another <?= View::make('subview')->with($vars->sub);?> within the the view. or just use the #extend functionality.
I don't entirely understand your question.
I think what you are looking for is a View Composer
It allows you to get data for a subview without having to create the data in every controller.
As I have understood, the main design idea of templating engines like Twig is to remove all PHP code from views, and to have the controller that renders a view have set all parameters that are necessary in that view.
However, imagine that a view consists of different "blocks": a header, a footer, a shopping cart and a productlist. You could have the order_controller.php check whether or not the customer is logged in (because if not, the header doesn’t contain the link "Log off"), as well as fetch a list of all available products (to show them in the product block), as well as fetch the contents of the shopping cart in the $_SESSION (to show them in the shoppingcart block).
However, it might be more interesting to have the order_controller only fetch one thing: the list of products. The view that will be rendered by the controller would then contain different includes for the other blocks (header, footer and shopping cart), but they wouldn’t include their views. They would include other controllers (showheader_controller, showfooter_controller and showcart_controller), which in turn would render their own single blocks (showheader_controller would only render the header-view etc…). In short: you would include controllers that render views in the main view. The logic that would check whether or not the customer is logged in would then be showheader_controller, for the simple reason that the header view is the only view that needs to know this. The logic that load the contents of the shopping cart from $_SESSION would be the showcart_controller, because the cart-view is the only view that needs to have access to this data, etc...
This way, you could have tons of controllers that all show the header, but the instead of having each controller repeat the logic to check whether or not the customer is logged in, you would only have it in one place (the controller that renders the header-view).
If there were a Twig function to include any external source on that spot in the view, the problem would be fixed (since I could just include the other controllers), but as it is it only allows for the including of other templates (that cannot have PHP-logic in them, otherwise it would kinda defeat the purpose).
The way I fix this now is to have the order_controller have this logic:
Fetch the productlist
Start the buffering of the outputstream (ob_start())
Include the controller that renders the header (showheader_controller)
Store the contents of the buffer in a variable $headerView.
Clean up the buffer
Start the buffering of the outputstream (ob_start())
Include the controller that renders the shopping cart (showcart_controller)
Store the contents of the buffer in a variable $cartView.
Clean up the buffer
Rinse and repeat...
In the view, I print the contents of the set variables:
{{ headerView | raw }}
The raw-filter has to be added, because the headerView variable contains html-tags.
It works perfectly, but it’s not exactly “neat”.
My question: would there be a better way to achieve this strategy?
First, this can be simplified by implementing the MVC separation better. The controller's job is pretty much solely to react to events and poke the model into doing appropriate things in reaction to this event. It is not the controller's job to hold hands with the view, nor is the view entirely dependent upon the controller.
The model is your core application, modeling all the things your application is supposed to do. The view's job is to visualize what is going on in the application, to give the user something to interact with. The controller is just a little glue between the user and your application, something that lets the user control the application.
As such, the controller reacts to events like "user visited homepage", triggers necessary events in the model, which causes the view to update to represent the new state of the application. The view can do whatever it needs to do. The view is not just a Twig template. The view can talk back to the model to get more information. In the end it is not the controller that needs to send necessary data to the Twig template, it's the view that needs to set the necessary data for the template before it renders it. Less code in controllers, more code in the view.
If you want to make this more modular, you can define custom Twig tags or functions which may fetch the necessary data from wherever it needs fetching. For instance:
<div class="head">{{ user_login_status() }}</div>
user_login_status is a Twig extension function which can talk to the model to get the data necessary to display the status.
Hope you get the idea.