Laravel Blade: What is nesting sections doing here? - laravel

I don't know what does putting a section inside another section do. In a Laravel project I'm reading, a Blade file's code is like this:
login.blade.php :
#extends('layout') #section('content')
#section('title', 'Log in')
Lots of content.
#endsection
In above, what's the point of having title section inside content section? How will it be different if title section is placed outside:
#extends('layout')
#section('title', 'Log in')
#section('content')
Lots of content.
#endsection
I tested, and both are producing same output (HTML source code).
layout.blade.php
<head><title>#yield('title')</title></head>
<body>#yield('content')</body>
Is there any case of layout.blade.php in which different outputs will be produced?

The section directive simply copies whatever you have within #section and #endsection to the name #yield place holder on the extended template.
This means it does not consider where its placed, but for clarity and readability, the second example is the right structure.
For example, this shows that the order of the directive doesn't matter
In welcome.blade.php
#extends('default')
#section('a')
This is a
#section('c', 'This is c')
#section('b')
This is b
#section('d', 'This is d')
#endsection
#endsection
In default.blade.php
#yield('c')
#yield('a')
#yield('b')
#yield('d')
The output
This is c This is a This is b This is d
The best practice is to make your code more readable by opening and closing each block:
#extends('default')
#section('a')
This is a
#endsection
#section('c', 'This is c')
#section('b')
This is b
#endsection
#section('d', 'This is d')

It's better to put them on different rows for readability sake.
First section just puts "Log in" wherever the section "title" is:
#section('title', 'Log in')
Second section has the beginning and the end and is selfdescriptive.

Related

jekyll filename for current file

The title says it all. Is there a way to access the current filename in Jekyll? Before you jump the gun and try to mark it as duplicate, keep in mind that I'm asking for the current filename, not for the generated filepath which can be access by page.url.
As an example, lets say that there is a file1.html which include file2.html. I want to be be able to get file1.html if I'm inside file1.html and file2.html vice-versa. page.path only returns the filename for the generated file as in I will get file1.html even from within file2.html.
A concrete example:
file2.html:
<div>
{{ page.name }}
</div>
file1.html:
<div>
{% include file2.html %}
</div>
index.html:
{% include file1.html %}
rendered:
<div>
<div>
index.html
</div>
</div>
Instead of index.html, I want it to return file2.html
Thanks
Edit : An include is just a fragment that is inserted into a page. Once every include are made, the page is then processed as a single block of code.
There is no way to get any info from liquid about an include name.b

Page Object Gem. Making accessors for elements without ids

Lets say I have a simple page that has less IDs than I'd like for testing
<div class="__panel_body">
<div class="__panel_header">Real Estate Rating</div>
<div class="__panel_body">
<div class="__panel_header">Property Rating Info</div>
<a class="icon.edit"></a>
<a class="icon.edit"></a>
</div>
<div class="__panel_body">
<div class="__panel_header">General Risks</div>
<a class="icon.edit"></a>
<a class="icon.edit"></a>
</div>
<div class="__panel_body">
<div class="__panel_header">Amenities</div>
<a class="icon.edit"></a>
<a class="icon.edit"></a>
</div>
</div>
I'm using Jeff Morgan's Page Object gem and I want to make accessors for the edit links in any given section.
The challenge is that the panel headers differentiate what body I want to choose. Then I need to access the parent and get all links with class "icon.edit". Assume I can't change the HTML to solve this.
Here's a start
module RealEstateRatingPageFields
div(:general_risks_section, ....)
def general_risks_edit_links
general_risks_section_element.links(class: "icon.edit")
end
end
How do I get the general_risks_section accessor to work, though?
I want that to represent the parent div to the panel header with text 'General Risks'...
There are a number of ways to get the general risk section.
Using a Block
The accessors can take a block where you can more programatically describe how to locate the element. This allows you to locate a distinguishing element and then traverse the DOM to the element you actually want. In this case, you can locate the header with the matching text and navigate to its parent.
div(:general_risks_section) { div_element(class: '__panel_header', text: 'General Risks').parent }
Using XPath
While harder to read and write, you could also use an XPath locator. The concept and thought process is the same as using the block. The only benefit is that it reduces the number of element calls, which slightly improves performance.
div(:general_risks_section, xpath: './/div[#class="__panel_body"][./div[#class="__panel_header" and text() = "General Risks"]]')
The XPath is saying:
.//div # Find a div element that
[#class="__panel_body"] # Has the class "__panel_body" and
[./div[ # Contains a div element that
#class="__panel_header" and # Has the class "__panel_header" and
text() = "General Risks" # Has the text "General Risks"
]]
Using the Body Text
Given the HTML, you could also just locate the section directly based on its text.
div(:general_risks_section, class: '__panel_body', text: 'General Risks')
Note that this assumes that the HTML given was not simplified. If there are actually other text nodes, this probably would not be the best option.

How to comment code in blades like laravel 4?

I have migrated my app from laravel 4.2 to laravel 5
I am currently having this problem, when even I have old comments like this:
{{--{{link_to_route('language.select', 'English', array('en'))}}--}}
Will result into error at laravel 5, I will have this error:
FatalErrorException in 18b6386ebc018eb0c0e76f105eba4286 line 263:
syntax error, unexpected '{'
which is compiled into:
<?php echo --{{link_to_route('language.select', 'English', array('en')); ?>--}}
I already added laravel 4 backward comparability support at register#ServiceProvider as:
\Blade::setRawTags('{{', '}}');
\Blade::setContentTags('{{{', '}}}');
\Blade::setEscapedContentTags('{{{', '}}}');
but how can I add laravel 4 backward comparability for comments {{-- --}} ?
edit:
how to comment this in laravel 5:
<li {{ (Request::is('/') ? ' class="active"' : '') }}>{{trans('messages.Home')}}</li>
Since you change your content tags from {{ to {{{ comment tags are now {{{-- not {{--
From lavarel 5 doc
Note: Be very careful when echoing content that is supplied by users
of your application. Always use the double curly brace syntax to
escape any HTML entities in the content.
{{-- This comment will not be in the rendered HTML --}}
So I think this should works :
<li {{-- (Request::is('/') ? ' class="active"' : '') --}}>
{{--trans('messages.Home')--}}
</li>
And to comment the whole HTML add :
{{{-- HTML --}}}
In general the comment syntax has not changed in Laravel 5, however...
The characters for comments are derived by the content tags. Since you set them to {{{ and }}} with Blade::setContentTags('{{{', '}}}'); you have to use them now for your comments as well:
{{{-- {{link_to_route('language.select', 'English', array('en'))}} --}}}

Laravel/Blade - Extend same template multiple times on same page

So there must be a simple way around this... On my site there are multiple modals, depending on the page. I've created a modal template that these can all extend. However, the last modal I include on the page ends up 'taking over' the rest of them, and so all my modals end up with the same sections from that last include. How can I make it so that each extension is unique to the file from which it extends?
Example of what's happening:
//template.blade.php
<htmls and stuff>
#yield('section_1')
#yield('section_2')
</htmls and stuff>
//Modal 1
#extends('template')
#section('section_1')
Some words
#stop
#section('section_2')
More words
#stop
//Modal 2
#extends('template')
#section('section_1')
Rabbit
#stop
#section('section_2')
Stew
#stop
Instead of two unique modals being loaded, I end up with two modals full of Rabbit Stew.
Try using the #overwrite command instead of #endsection
Example:
#section('stuff')
Stuff goes here...
#overwrite
Source: https://github.com/laravel/framework/issues/1058#issuecomment-17194530
I personally would use includes in this instance, unless you've got markup in your sections. If it's just text you could do something like this:
//template.blade.php
<htmls and stuff>
{{ $section1 }}
{{ $section2 }}
</htmls and stuff>
//Modal 1
#include('template', ['section1' => 'Some words', 'section2' => 'More words'])
//Modal 2
#include('template', ['section1' => 'Rabbit', 'section2' => 'Stew'])
I had the same problem. I really wanted to use Blade templates too, but ended up using php includes, even with basic html markup.
//Modal 1
#include('layout.template', array(
'section1' =>
'<h1>Modal 1</h1><p><b>Some</b> words</p>',
'section2' =>
'<p>Some <u>words</u></p>'
))
//Modal 2
#include('layout.template', array(
'section1' =>
'<h1>Modal 2</h1><p><b>Some</b> words</p>',
'section2' =>
'<p>Some <u>words</u></p>
'
))
The markup all works just fine, including links. Where I ran into trouble was when I wanted to use includes inside the include arrays, which I understand is not possible. That is why I wanted to use Blade Templates.

Can blade yield to a section in the same file?

I have file master.blade.php, which contains #yield('mainsection'). Then I have another file, with:
#extends('layouts.master')
#section('mainection')
test1
#yield('othersection')
#stop
#section('othersection')
test2
#stop
I can see test1, but not test2 - from which I conclude that blade does not allow you to yield to a section defined in the same file. Is there any way to work around that? Or will I have to add a third file between these two, to contain the mainsection and yield to othersection?
it can be shown, but #section must be written before #yield
#extends('layouts.master')
#section('othersection')
test2
#stop
#section('mainection')
test1
#yield('othersection')
#stop

Resources