In blade, you can create stacks. See the following for more information:
https://laravel.com/docs/5.2/blade#stacks
However the above link only shows how to push elements to the end of the stack.
I want to append an element to the start of the stack. How can I do this?
e.g.
#push('foo')pizza #endpush
#push('foo')like #endpush
#push('foo')I #endpush
#stack('foo')
outputs:
pizza like I
I want it to output:
I like pizza
This is something that I wouldn't recommend doing because this is the way Laravel is built.
But, if for any reason, you need it so much and you don't see any other way to accomplish it, You can tweak the framework itself.
The file Factory.php is located in Illuminate\View. over there you have a function called extendPush() and you can change the "Append" method by replacing the line:
$this->pushes[$section][$this->renderCount] .= $content;
with this:
$this->pushes[$section][$this->renderCount] = $content . $this->pushes[$section][$this->renderCount];
in the last else statement.
Again, I wouldn't recommend tweaking the framework but if it's that important to your project than this is what I can offer.
You can create in your blade #stacks everywhere. If you like a stack in the header put in your blade:
<head>
...
#stack('myScriptsAbove')
...
</head>
Then you can push the scripts from other blades to it. Like that #push('myScriptsAbove)`.
In my case, the Parent-Blade file's #push(...), did somehow append after that of Child-Blade file.
But nowadays, we can simply use #prepend, like:
#prepend('css')
<link href="{{ asset('css/app.css') }}" rel="stylesheet"/>
#endprepend
Seems in Blade, #stack works like LIFO queue (Last-In-First-Out);
So, #push and #prepend each do the exact opposite of what I did expect.
Related
Note: Like i said in the comment, i am working relatively large project. I can't change existing codes. Just try to add some code blocks for one page.
I have a template blade. It has meta yield. But also included one meta.blade.php, that contains all meta tags. But i don't want to include metapage for some of my pages. There is the template for visualization:
my_template
<header>
#yield('meta')
#include('metapage')
#yield('style')
#yield('js')
</header>
my view.blade.php
#extends('my_template')
#section('meta')
<meta description...>
#endsection
#section('style')
//content
#endsection
#section('js')
//content
#endsection
My question is: Is there a way to make something like this:
#extends('my_template')->except('metapage')
I know there isn't exist something like that. But i need that. I hope somebody can give me a solution.
There is a certain solution which I do:
First one is to create multiple template and extend them as your requirements.
Second one is to disable sub parts.
Third one to create parent template having little things, then create child template which is extending parent and do extra things here. use it as your need.
If You are working on existing project and you have a lot of pages then First & third one is a better solution for it because you could make changes only in front end without affecting class code.
You could make the meta a component rather than an include, then your template would look the same and your view would be e.g.
#extends('my_template')
#section('meta')
#component('meta')
#slot('description', 'my amazing description')
#endcomponent
#endsection
// other code here as usual
Your component is then responsible for checking what exists and what doesn't, e.g. like this:
#isset($description)
<meta name="description" content="{{ $description }}">
#endisset
#isset($title)
<title>{{ $title }}</title>
#endisset
// etc, the title is just an example
Documentation: https://laravel.com/docs/5.6/blade#components-and-slots
Take the Tag Name Which You Want To ignore And Apply the CSS
ex: If I need to Remove the Footer From the Extended Page make
footer {
display: none;
}
I've got specific Form component, which is declared as
Form::component('fcRadio', 'components.form.fcradio', ['name', 'options', 'selected' => null]);
and used as
{{ Form::fcRadio('name', $options }}
What I want is somehow attach custom CSS file, so if the page fires this component at least once, the desired CSS file is included to the <head> of my document.
For example, in Joomla it was like
$this->document->addStylesheet('my_awesome_style.css');
Is there any way to achieve the same in Laravel?
UPD:
I've extended the answers below a bit to let it add multiple styles from multiple templates. Finally, it looks like this:
#section('styles')
#parent
{{HTML::style('css/fcradio.css')}}
#stop
It works fine, but if I use the component twice per page, style is also adds twice. How can I allow multiple but unique entries?
So this is typically how I deal with it:
In your folder: resources/views I create a folder called layout. This folder handles the templates for all my pages.
Then I create a file called default.blade.php. In it I put the bulk of the HTML code. Here's an example of how default.blade.php could look (slimmed down, obviously)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="x-ua-compatible" content="ie=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>
#yield('title')
</title>
<link rel="stylesheet" href="{{ asset('css/main.css') }}">
<!-- Additional per-page css -->
#yield('css')
</head>
<body>
#yield('content')
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.4/jquery.min.js"></script>
<script src="js/script.js"></script>
<script src="{{ asset('js/bootstrap.min.js') }}"></script>
<!-- Include per-page JS -->
#yield('js')
</body>
</html>
Right, so essentially what we have so far is the #yield() and asset() helpers.
#yield() is special blade syntax that Laravel uses to say, "Okay. Any time a blade view that is inheriting THIS master template calls the section named in this #yield() I will display that content right here.
asset() is a nifty little helper that basically appends your URL structure onto the string you pass it. So if your url is http://MyGreatSite.com and you use asset('js/script.js') it will spit out a fully qualified URL that will work anywhere on the site (http://MyGreatSite.com/js/script.js). asset() is great because you can use it in blade templates that will get sent out as an email and all of the files will work in an email inbox because they are absolute links.
Right. So now we have this master template and we need to use it. So what I do is create another view in the resources/views directory. Lets say we're doing a contact page. I would make contact.blade.php. Now I want to inherit that master template we created. So we do that like so:
#extends('layout.default)
#section('css')
<link rel="stylesheet" href="{{ asset('css/contact.css') }}">
#stop
#section('title')
Contact Us
#stop
#section('content')
<h1>Contact us</h1>
<p>
Contact us via email: contact#mygreatsite.com
</p>
#stop
#section('js')
<script src="{{ asset('js/contact-form.js') }}"></script>
#stop
Okay, so, first things first. At the very top we tell this blade file that we want to use the template we just made. We use the blade helper #extends() and pass it the path to our view relative to the views directory separated by periods.
Next, we want to create the sections that correspond to the template. We do that by opening the section with #section() and passing the name of the section we want to push this block of content to. We write our content and then we close the section by using #stop. Pretty simple. For images, css, or js, we simply use the asset() helper again.
I know it's a little long-winded, but hopefully that helps and explains the process a little better.
tl;dr: Use #yield(), #section(), and asset().
So I think I understand what you are saying.
In your blade layout file create a section inside the head:
<head>
#yield('componentcss')
</head>
And in the component do:
#section('componentcss')
{{HTML::style('css/fcradio.css')}}
#stop
You could also just include the css but I wouldn't advise this:
#section('componentcss')
<style>
.exampleclass {text-align:center;}
</style>
#stop
Hopefully I have understood you correctly.
I've finally found a bit tricky but working solution:
#hasSection('fcRadioStyle')
#else
#section('fcRadioStyle')
{{Html::style('css/components/fcradio.css')}}
#stop
#section('styles')
#yield('fcRadioStyle')
#append
#endif
This makes by Form::fcRadio append this style only once
Im trying to include a partial, that extends another partial.
Like #include('B')and B looks like
#extends('A')
#section('content')
Some stuff here
#stop
But it seems that only Some stuff heregets displayed, but not the things of partial A. Do you have any fixes for that?
Thanks
Seems like you're trying to use partial B that extends template A
If you need to append data, you can use the #parent or #append notation, like so:
#extends('A')
#section('content')
#parent
Some stuff here
#stop
This will append parent data from template A's content section, inside template B
More info at Laravel's Blade documentation
Actually this works. The problem here was the non-unique use of the #section Identifier. (In the base Template and in the partial)
Simplified my main.blade.php template looks like this...
<html>
<head>
#inlcude("header")
#yield("addToHeader")
</head>
<body>
#yield("content")
#include("footer")
</body>
</html>
Let's say my controller points to login.blade.php and it provides addToHeader and content sections. When my footer is included, I'd like to append the addToHeader section but I just can't get it to work.
In my footer I have tried
#section("addToHeader")
#parent
This is the added content
#yield("addToHeader")
#stop
And variations of this.
Now, for the sake of doing it right and in hopes that I might not spend my resources on doing this the incorrect or inefficient way, here is what I am trying to accomplish by doing this...
When a user logs in every time they try to load a new page, I want the website to throw a message to the user (in my case I am actually "locking" the page down with a modal) that lets the user know he/she must finish setting up her profile before anything else can be done. Is there a controller or route that doesn't care which page/action is being requested and allows me to send extra data to the template - even if it is just $data["lockdown"]=true?
I don't know if it's the best way to do it but i would go for something like this.
Using a session variable to know if the user has to set-up his profile or not:
Session::put('profile_uncompleted',true);
You can set this variable when the user log-in for exemple.
Then on your main.blade.php you can check if you have to display your modal:
#if(Session::has('profile_uncompleted')
#include('modal')
#endif
Where modal contains your Html modal content.
I have searched SO, and dug in the Laravel documentation but I am not sure I quite understand if what I would like to do can be done.
I am using Laravel 4. I want to know how I can nest views in other views.
For example, I have a base layout.. lets call it layout.blade.php
<html>
<head>
<title>{{ $title }}</title>
</head>
<body>
#yield('nav')
#yield('content')
</body>
</html>
Next I have a blade for a page called home:
#extends('layout')
#section('nav')
<p>NAVIGATION</P>
#end
#section('content')
<p>HELLO WORLD!</P>
#end
I have a couple different navigation layouts, one for admins, another for super users, and another for regular users.
Is there a way to add another blade view inside the section('nav')?
#section('nav')
// do something magical here?
#end
It doesn't make sense that for every blade layout I need to repeat the navigation code when several snippets can be reused.
You can do this
#section('nav')
#include('another')
#include('magical')
#include('snippet')
#end
Another solution, in case you were wishing to dynamically load different subviews, you can nest using the View Class. E.g. you could have the following in a Route / Controller:
return View::make('home')->nest('subnav','home/nav', array('some' => 'data');
and then in your home.blade.php, you could do this:
#extends('layout')
#section('nav')
<p>NAVIGATION</p>
{{ $subnav }}
#end
#section('content')
<p>HELLO WORLD!</p>
#end
This can be done with an include and a variable as well (#include($viewname, array('some' => 'data')) however I'd say its cleaner as it removes the logic from the view, particularly if your nested views aren't always the same blade file.
Even though this is late you can also do this:
eg. in an admin.php you can have this:
#extends('home')
#section('nav')
// navigation
#endsection
#section('content')
// admin page content
#endsection
Not saying this is better or not i'm just answering your question on nesting views with blade, this is how i nest my views.