Laravel blade templating discrepancy - laravel-4

I have main layout template /views/web/main_lo.blade.php as
<html>
<head>
<meta charset="UTF-8">
<title>{{$title or 'Default Title'}}</title>
</head>
<body>
<div class="section-1-outer">
#section('section-1')
<div class="section-1-parent">parent section 1</div>
#show
</div>
<div class="section-2-outer">
#section('section-2')
<div class="section-2-parent">parent section 2</div>
#show
</div>
<div class="section-3-outer">
#section('section-3')
<div class="section-3-parent">parent section 3</div>
#show
</div>
<div>
#yield('content')
</div>
</body>
</html>
and a section template as:
#extends('web.main_lo')
#section('section-1')
#parent
<div class='section-1-child'>
<p>Appended to parent</p>
</div>
#stop
#section('section-2')
<div class='section-2-child'>
<p>Replace parent</p>
</div>
#stop
#section('section-3')
<div class='section-3-child'>
<p>Replace parent</p>
</div>
#overwrite
Now here section layout is extending main_lo, here First section-1 which is quite clear that child section will include parent section-1 and content in parent section will also be printed.
Now my confusion is what on earth is difference between section-2 and section-3 implementation as they both replace content of parent section and only content in child get printed. I mean what is need of this extra #overwrite tag when documentation clearly states that
"Note that views which extend a Blade layout simply override sections
from the layout."
and then there is Overwriting Sections using #overwrite which is also for replacing content of parent section.

Laravel view's sections are a bit oddish and the bad part is that it's not obvious from the start.
Sections are actually extending in converse order, the section defined first will be the child and the one later will be the parent. So #parent is actually including the content of the section which may come after.
This is why I think parent and child are not the best terms for this system.
This is not obvious because of the conventional use case - layouts - it looks like the layout sections are the ones defined first. But actually they ran after the content sections are rendered.
This means #overwrite is actually used with the parent section, not the child. Which wouldn't make much sense in your example as you're yielding (#show) in the layout too, meaning you don't want to overwrite there.
The reason for this is actually because #overwrite was made for less conventional use cases, not when you have a layout-content, parent-child relationship.
Most often this happens when you include some partial files - maybe all over the place - where you use the same section names and you run into a problem when the earlier defined section is the one showing instead of the later.

Related

Laravel with blade - multiple inheritance

I know there was many question like this one but I still can't handle with that problem.
I have master layout where I put common elements for all subsites in my app.
(Inside common directory)
<!DOCTYPE html>
<html lang="pl">
<head>
#include('common.head')
</head>
<body>
<div id="l-wrap">
#include('common.header')
<article id="l-content">
#yield('content')
#include('common.dealer-area')
</article>
#include('common.footer')
#include('common.cookies')
</div>
If I understand correctly: if I want elements 'stick' to master template I make include, these elements will be this same on every subpage.
Second blade inheritance after first one and looks like this:
(Inside homepage directory)
#extends('common.template')
#section('content')
#yield('slider')
#endsection
And there is third blade which inheritance after second one:
#extends('home-page.template')
#section('slider')
<div class=slider> Some slider elements
</div>
#endsection
But view from third section doesn't show at all. I tried with #yield, #section...#endsection, or #section...#stop but it doesn't helped.
When I give second parameter in #yield function, after 'slider' in second blade:
#yield('slider', 'some text')
It shows correctly so I think problem is the last one blade, the third one, do I use inheritence incorrectly?

AngularDart: How to change partial parts of layout based on navigation?

Say I have this simple scaffold in my app_component.html:
<header>
<div>
<!-- here I have some elements that won't change -->
</div>
<div>
<!-- SECTION HEADER: but I want to change this part's content, based on
navigation or something else (auth roles, for example) -->
</div>
</header>
<main>
<div class="container">
<div class="row">
<div class="col s12">
<section class="section">
<router-outlet>
<!-- SECTION MAIN: main content goes here -->
</router-outlet>
</section>
</div>
</div>
</div>
</main>
<div class="divider"></div>
<footer>
<div>
some footer here. nothing important
</div>
</footer>
As you can see in the snippet, I'm using a <router-outlet> in SECTION MAIN to show contents which is fine. The problem is, how can I have a changeable part in header section (the SECTION HEADER in the code) and how can I change it's content based on e.g. navigation, auth roles, etc. ? Does AngularDart support this kind of routing? Thanks in advance.
The short answer is no, the router doesn't currently have support for doing this easily.
Other frameworks support this functionality through "named" router outlets. This allows multiple outlets to exist in the same view, provided they're given unique names. Each route configuration then must designate which component is rendered in which named outlet. If this sounds desirable, please feel free to file a feature request: https://github.com/dart-lang/angular
Of course you could always write your own solution. You could create a component for the header section that dynamically loads a different component, depending on which route is active. It simply needs to inject Router and listen to Router.stream for route changes.

BEM: Nested Blocks, what is the best approach?

In the following markup, what is the best BEM approach?
This?:
<footer role="footer">
<footer class="footer__inner">
<div class="footer__left">© Some text</div>
<div class="footer__right">Some text</div>
</footer>
</footer>
OR this?:
<footer role="footer">
<footer class="footer__inner">
<div class="footer__inner__footer__left">© Some text</div>
<div class="footer__inner__footer__right">Some text</div>
</footer>
</footer>
Or none of them are right and you know a better way?
Thanks
You want to have clean reusable blocks. Ask yourself which part you might want to reuse.
Multi level nesting of blocks are frowned upon. And that's for a good reason. In case of reusability there should only be one block as root reference. Everything below that one block is, from a bem syntactic point of view, simply an element of that block. Not a sub-block, not a sub element, but only an element.
So, BEM doesn't care about your HTML structure. It's much more a question of what purpose a block or an element has.
I can't really tell from your example what the purpose of your nested footers might be, but it looks to me as if you consider the role attribute of your outer footer element as part of BEM-naming. But it's not. Keep in mind the idea of separation of concerns. role="footer" is HTML semantic. You should not use it as BEM naming reference because you might want to change that HTML attribute one day and then your BEM semantic would go up in smoke.
So, here's what I would do.
Let's say you want your outer footer to be the reusable element then you might want to name your classes like this (just as an example):
<footer class="footer" role="footer">
<footer class="footer__textbox">
<div class="footer__text footer__text--left"> <!-- left as modifier -->
<div class="footer__text footer__text--right"> <!-- right as modifier -->
</footer>
</footer>
Now you can take your footer and use it in any appropriate section of the page and anyone reading your code can get grasp an idea about the purpose of this css structure.
First variant looks fine for me.
Second is wrong as you shouldn't reflect DOM structure in class names. See https://en.bem.info/methodology/faq/#why-does-bem-not-recommend-using-elements-within-elements-block__elem1__elem2
Markup suggest by LongHike is also good.

What's the difference between Laravel Blade's `#yield` and `#include`?

I'm learning Laravel (starting at version 5.3) and these two Blade directives look very similar, the only difference I know is that #include injects the parent's variables and can also send other variables.
What's the difference between #yield and #include?
When should I use #yield?
When should I use #include?
#yield is mainly used to define a section in a layout. When that layout is extended with #extends, you can define what goes in that section with the #section directive in your views.
The layout usually contains your HTML, <head>, <body>, <header> and <footer>s. You define an area (#yield) within the layout that your pages which are extending the template will put their content into.
In your master template you define the area. For example:
<body>
#yield('content')
</body>
Let's say your home page extends that layout
#extends('layouts.app')
#section('content')
// home page content here
#endsection
Any HTML you define in the content section on your homepage view in the 'content' section will be injected into the layout it extended in that spot.
#include is used for reusable HTML just like a standard PHP include. It does not have that parent/child relationship like #yield and #section.
I highly suggest reading the Laravel Blade documentation for a more comprehensive description.
#include and #yield are two completely different types of operations to import code into the current file.
#include - import the contents of a separate file into the current file at the location in which it is placed. i.e.:
Layout file:
< some html or other script >
#include('include.file_name') // "include." indicates the subdirectory that the file is in
< more html or other script >
Include File ( a blade file with a block of code ):
< some cool code here >
The contents of 'file_name' ( also a blade file ) is then imported in where the #include directive is located.
#yield imports code from a "section" in the child file ( the "view" blade file. ) i.e.:
Layout file:
< some html or other script >
#yield('needed_section_name')
< more html or other script >
The following section is needed in the "view" blade file that is set to "extend" that layout file.
"View" blade file:
#extends('layout.file_name')
... code as neeeded
#section('needed_section_name')
< some cool code here >
#stop
...
more code as needed
Now the layout file will import in the section of code that matches the naming used.
More on the subject here....
The difference between #yield and #include is how you use them.
If you have a static kind of content, like a navbar, this part of the page will always be in the same place in the layout. When you use #include in the layout file, the navbar will be put once per layout. But if you use #yield you will be enforced to make a #section of the navbar on every page that #extends the layout.
#yield is, on the other hand, a better choice when content is changing on all the pages but you still want to use the same layout everywhere. If you use #include you'll have to make a new layout for every page, because of the difference of content.
Today I was trying to figure out this difference as well, and where to use each, and why would I want to use one over the other. Please be warned this answer is verbose and probably very over-explained.
Snapey from the Laracasts forums got me started thinking about them properly:
https://laracasts.com/discuss/channels/laravel/whats-the-difference-between-atinclude-and-atyield
First off, #include is going to include an entire file, just like the PHP include function. That's great if you're just dumping an entire file of content into the <body> of your page, for example the following is going to include everything inside of 'content.blade.php':
<!-- layout.blade.php -->
<body>
#include('content')
</body>
<!-- content.blade.php -->
<div>
<div>
<p>Hey this is my content.</p>
</div>
<div>
<span>and stuff</span>
</div>
</div>
But #yield, in conjunction with #extends and the #section and #endsection directives, will allow you to have your content chunked into separate sections, but kept all in one file. Then you can #yield it into the layout in separate chunks. The visual that comes to mind is shuffling one half of a deck of cards into the other half, in a classic "riffle" shuffle:
<!-- content.blade.php -->
#extends('layout')
#section('top_content')
<h1>Hey I'm the title</h1>
#endsection
#section('middle_content')
<p>Hey how's it going</p>
#endsection
#section('other_content')
<p>It's over now.</p>
#endsection
<!-- layout.blade.php -->
<body>
<div>
#yield('top_content')
</div>
<p>Some static content</p>
<div>
#yield('middle_content')
</div>
<p>Some more static content</p>
<div>
#yield('other_content')
</div>
<div>Static footer content of some kind</div>
</body>
Secondly and maybe more importantly, the flow of control is sort of inverted, in a way that makes everything much more coherent. In the first example, with #include, you'd be calling the layout file with the view helper, in sort of a top-down way. For example this might be your code:
Route::get('/', function () {
return view('layout');
});
But with #yield and #extends, (as in the second example) you call the content file itself, and the content file will first look at the #extends directive to drape itself with the layout file, like it is putting on a coat. So it happens in reverse, in a sense, like bottom-up. Then the #yield directives inject the content as specified. The content file is who you are talking to in your router/controller:
Route::get('/', function () {
return view('content');
});
You call the content view, it looks at the #extends directive to pick the layout, and then the #yield directives in the layout file inject the matching #section sections into the layout.
So this way is much more useful because in practice you'll be referring to different content when you refer to different views.
If you were only using the #include statement to build your views, then you'd have to pass a different content slug to the layout file that you are calling every time, maybe like this:
Route::get('/welcome', function () {
return view('layout', ['content' => 'welcome']);
});
Route::get('/profile', function () {
return view('layout', ['content' => 'profile']);
});
<!-- layout.blade.php -->
<body>
#include($content)
</body>
And that seems like a mess to me.
That all being said, #include seems like a great way to include a little snippet in your layout file (the one called by the #extends directive), like the nav bar, or the footer, or something you just want to separate out of your layout file for organizational purposes.
#yield should be used when your contents will be changed
#include should be used for contents that wont change. e.g header, footer
#include used for reusable code like navbar, we have to design navbar one time and use it in our whole site.
#yield used for sections that change again and again like body.
for example you have already your layout structure where you #include('some scripts or style'). it will not allow you to change its directive while #yield you can change its content. means you create a section to yield into your layout.blade.php. you can use yield also if you have a specific script or style in each page.
#include('layouts.nav') //default when you call layout.blade.php
<div class="container">
#yield('content') //changes according to your view
</div>
#include('layouts.footer') //yes you can use #yield if you have specific script.

Blade: extending a template in multiple subviews

I am using Blade to include multiple sub-views into a single set of tabs in a blade app. All of the sub-views have the same overall structure (a sidebar and a main section). Because of this, I have created a template and each sub-view extends the template. Here is the structure:
Main.blade.php
<div id="tabs">
<ul>
#foreach($views as $view)
<li>{{$view}}</li>
#endforeach
</ul>
#foreach($views as $view)
<div id="{{$view}}">
#include($view)
</div>
#endforeach
</div>
template.blade.php
{{-- formatting stuff --}}
#yield('content 1')
{{-- more formatting stuff --}}
#yield('content-2')
{{-- more formatting stuff --}}
tab-*.blade.php
#extends('template')
#section('content-1')
This is tab [whatever number]
#stop
#section('content-2')
Lorem Ipsum
#stop
The obvious problem here is that, as each sub-view extends the same template, the #yield('content') exists 3 times, and all 3 included sub-views have their own #section('content'). What appears to be happening is that the first sub-view's implementation of the content section is getting placed in all 3 yields.
My intent here is obvious. I want each included sub-view to implement it's own instance of the template, place it's content in the content section, THEN get pulled into the main page. Can this be done?
If I flatten the tab-*.blade.php files and stop using the template, it works fine. The problem here is that I end up with a lot of code repetition that would be better placed in a template. This is an emergency option, but I'd like to do it the "proper" way.
NOTE
I have tried to redesign this to avoid the problem, but I really can't come up with another solution. While #include is typically used to pull in small, static pieces (a header, a footer, etc.), I have not read anything that states this as a restriction. It seems to me that the best approach is to store each view once and pull them into the main page when needed, so that's how I've designed it.
Try using the #overwrite command instead of #stop
Example:
#extends('template')
#section('content-1')
Stuff goes here...
#overwrite
#section('content-2')
More stuff goes here...
#overwrite
Source: https://github.com/laravel/framework/issues/1058#issuecomment-17194530
I came up with a hack that seems to work. In template.blade.php, I use the following:
{{-- formatting stuff --}}
#yield(isset($tab) ? "content-1-$tab" : 'content-1')
{{-- more formatting stuff --}}
#yield(isset($tab) ? "content-2-$tab" : 'content-2')
{{-- more formatting stuff --}}
Then, in main.blade.php, I execute #include('view', ['tab'=>$view]). This seems to cause each instance of content-1 and content-2 do be named distinctly, allowing the 2 subviews to implement the sections separately. This also should allow any other views that implement this template to continue to function without having to change anything.

Resources