Laravel: How to use composer to inject data across all views? - laravel

I want to offload some HTML sections of my site into partials (includes) files rather than repeating the information in each view or layout. However, I also need them to contain specific data. An obvious example is the head section; I would like to put this into a partial, however I also want to be able to set the document title and META fields for each page.
I think the best way is to use Laravel's view-composer
As per the docs, I can use an array to define the composer for multiple views at once:
View::composer(array('view1','view2', 'view3'), function($view)
{
$view->with('count', User::count());
});
However, what if I want to use this composer for every view, as I do in this case?
There's a few answers kicking around SO (such as this one) which suggests I use a wildcard. So here's my code:
View::composer('*', function($view)
{
$view->with('header', View::make('partials.head', $view->getData()));
$view->with('footer', View::make('partials.footer', $view->getData()));
});
Here's the problem: Using this is currently giving me an out of memory error, which suggests that it is very inefficient (and therefore that I really shouldn't be doing this).
So do I really need to pass an array listing every page on my website?
Isn't there a way to use composer for every page rendered, like I can with View::share(); ?

If the data is going to be unique for each view, there's no point in putting it in a view composer; you can do this just by using blade templates, and pass the page-specific data to the view from your controller.
Set up header and footer partials, then set up a base template that uses #include to load your header and footer partials, then a section for your content with #yield('content').
<!DOCTYPE html>
...
#include('partials.header')
#yield('content')
#include('partials.footer')
...
Then your individual page's views would each extend this base template:
#extends('base')
#section('content')
//...specific page content here
#stop
In your header and footer partials, include {{ $someData }} for whatever specific needs to change from page to page, and pass that data to each view from the controller.

This is now possible in Laravel 5.5
Put this is your AppServiceProvider boot method:
View::share('data', [1, 2, 3]);

Related

Laravel template snippets

Is this any possibilities to make code snippets in Laravel Blade templates ?
I need to do something similar like was in Smarty - you place [tag param1="value" param2="value"] and It's going throught function tag with render specify template under it.
Yes, this is possible by using either Components or Include. These allow you to create so called sub-views that can be called multiple times on a page with a number of parameters.

Target multi-page content in Joomla 3.0?

I managed to do this by using an override for the category blog (com_sontent/category/tmpl/blog.php). There I used the following to differentiate between paginated and not-paginated content and to hide/show code elements via CSS.
<div class="category-desc pages<?php echo $this->pagination->get('limitstart'); ?>">
I would like to apply the same method to my template's index.php, for example wrap the component output in a container with a CSS class name indicating if the content is broken up into several pages or not.
This would make it possible to hide side bars from a paginated blog main page, whereas they would show in single (unpaginated) articles linked to from this page.
Unfortunately, my knowledge of PHP barely exists.

Joomla 2.5.8. How to display only article or module content in modal box popup.

I want to put login module in to modal popup. But when I use class="modal" whole page gets loaded in to modal. Can you show me the way to put only module.
This stands also for displaying articles in modal.
here is the link with problem
I do this fairly often and there are two tricks that can help make this work better. First you will likely want to add tmpl=component to your url. This causes Joomla to only display the article instead of the entire template (as long as your template supports this, most do).
This should do pretty well. If you want to get even more selective, you can do one of two things:
Add CSS to hide pieces
.modal-body .other-selector {
display:none;
}
Use Javascript to select only the piece that you want
$('#myModal').on('show', function () {
// selects a piece of the current modal body and sets it as the only content of the modal
$('#myModal .modal-body').html($('#myModal .modal-body').find('.other-selector).html());
})
The way you can only display the component is to add an extra parameter tmpl=component in the url.If you'll see the component.php inside your template folder that has mainly <jdoc:include type="component" /> with no module position.So it'll load only component.
I did not try for module but you can try similar for module.So you can try it by just giving the position of the module in whole template like create a new page called modules.php in your template folder and put the module position inside this page.And you call it in a similar way just like component like tmpl=modules
I hope this will work.
It was problem with my templates component.php file. I just added inside and now it works fine. Thanks guys

how to apply css class on body tag using c# files

I'm using ASP.NET MVC3 with razor engine.I want to apply css class on body tag according to page call.
I want to add class name in child page and it will affect on layout page which has body tag.
and don't want to use jquery because it execute after page render.
How can i do this?
While you may have full control of the HTML a solution was what was needed so here is one ;-)
In the _layout.cshtml page
<body class="#RenderSection("BodyClass", false)">
This will look for a section in all the child pages but says don't worry if it can't find one
Then in your child views just do this
#section BodyClass {productList}
Keep it on one line and then the outputted HTML will look fine, also you can then build up the class names as well.
#section BodyClass {productList generic}
This idea goes perfect with DOM-Ready page specific code, why not checkout
http://paulirish.com/2009/markup-based-unobtrusive-comprehensive-dom-ready-execution/
Or my extended version here
https://github.com/AaronLayton/H5BP-Core
My way lets you do page specific code, but allows you to keep all of the Javascript in separate pages so each page becomes easily manageable. The final step would be to concatenate and minify all the JS into 1 file ;-)
Aaron's answer above works great for MVC 3, but I found that MVC 4 chokes on the single line section statement:
#section BodyClass {productList}
Instead, you need to use:
#section BodyClass {#("productList")}
First of all jQuery's .ready function executes after the DOM is available so it's the optimal moment to start interaction with your page's elements. ( http://api.jquery.com/ready/ ) If you experience a behavior that results in styles 'flicker' you may wan't to apply display:none to body element, and removing it after you css class has been applied.
but if you really don't want to use jQuery you should consider either making a variable to hold your css class name as a part of a viewmodel your controller will be sending to Views, or going with ViewBag.CssClass that should be declared in each of your controller's actions (or in base controller's OnActionExecuting method.
Thing to consider here is understanding and following MVC pattern, where View and Business Logic should be separated. So in my opinion you should rather avoid involving controllers in view building process.
It's much easier to simply put the following in your main layout
<body class="#ViewBag.BodyClass">
Then in the content pages put:
#{
ViewBag.BodyClass = "myClass";
}
Problem solved!

joomla add view into another view

Im using joomla MVC and I want to build a form that has different tabs which are different sections of the form with inputs in it. There are some tabs that are common to other forms that I need to include.
I would like to be able to load this common content from a separate file or view so i dont have duplicate code, plus is easier when I need to do a change to the form so I dont have to do it in all the forms. It's like displaying a view inside another view.
Is there a way to accomplish this?
A Joomla! provides the loadTemplate method to views.
So if you're currently in a tmpl file loaded for layout edit (ie. tmpl/edit.php ) you can call $this->loadTemplate('tab1'); and Joomla! will load the tmpl/edit_tab1.php file in the same view as your edit.php.
In that same view if you wanted to include say tmpl/other_tab1.php you would have to temporarily set the layout to other, eg. in one of our components during the Run template we need a tab from the Edit template, so we use:
<?php $this->setLayout('edit'); // This is ugly
echo $this->loadTemplate('plan');
$this->setLayout('run'); ?>
To load a template from another view alltogether, I think you would have to temporarily over-ride the view value, load the template then restore the view. eg.
$jinput = JFactory::getApplication()->input;
$jinput->set('view', 'other');
$this->loadTemplate('tab2');
$jinput->set('view', 'original');
NB: this last bit I haven't had time to test but it should work.
You can load a different template file for a different view manually, by simply requiring it. The following is for a view called "nameofotherview" with the layout "layoutname". If this is for an admin view use JPATH_COMPONENT_ADMINSTRATOR instead.
require(JPATH_COMPONENT_SITE . '/views/nameofotherview/tmpl/layoutname.php');
Remember that the data set up in the view class needs to be compatible with the main layout as well as the layout you're loading from elsewhere.
A side effect of doing this is that template overrides won't work. The loadTemplate function is doing a require but it checks the template paths for overrides first.
You can use vews in other views as described in Joomla documentation: Sharing layouts across views or extensions with JLayout

Resources