Using Multiple Yields to Insert Content

Using multiple yields to insert content

So, when you go to the index page you will get the piece of html that will be placed in the main layout, and this piece of html look like this:

<div class="container">
<%= render 'admins/menu' %>
<%= yield :admin %>
</div>

This code will yield :admin properly.

When you go to the test page you do not have this html code anymore (since it only belongs to the index method). So, anything you put in the content_for(:admin) block will be ignored since no-one is printing it.

What you probably want to do is creating a shared layout for all your admin pages. Follow this guide and you'll have your solution.

Solution

Edit the application.html.erb layout using this:

<%= content_for?(:content) ? yield(:content) : yield %>

instead of

<%= yield %>

Then create an admins.html.erb file inside the layouts folder to handle your admin pages' layout. Something like this:

<% content_for :content do %>
  <div class="container">
<%= render 'admins/menu' %>
<%= yield %>
</div>
<% end %>
<%= render template: "layouts/application" %>

Will do fine. Then in the index.html.erb and test.html.erb just place regular HTML content, without using the content_for(:admin) block. Everything should work fine and you'll have your custom admin template, with a slightly different look from regular pages.

Using multiple @yields with Laravel

Based on my tests, your example demo in the question works fine without any issues. Template inheritance.

Nonetheless, you may try making use of the "modern" anonymous components.

Anonymous Components

Similar to inline components, anonymous components provide a mechanism
for managing a component via a single file. However, anonymous
components utilize a single view file and have no associated class. To
define an anonymous component, you only need to place a Blade template
within your resources/views/components directory.

resources/views/components/layouts/master.blade.php

<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>{{ $title ?? 'Test' }}</title>
</head>
<body>
{{ $content ?? '' }}
{{ $content2 ?? '' }}
</body>
</html>

resources/views/welcome.blade.php

<x-layouts.master>

<x-slot name="title">
Test
</x-slot>

<x-slot name="content">
<h1>Test</h1>
</x-slot>

</x-layouts.master>

resources/views/test.blade.php

<x-layouts.master>

<x-slot name="title">
Test2
</x-slot>

<x-slot name="content2">
<h1>Test2</h1>
</x-slot>

</x-layouts.master>

Laravel adding Multiple yield to a single section

One way to achive what you want is to have the content of 'people' and 'contact' in other view. Then you will can include them in main 'people' and 'contact' views, and in any other view:

app.blade.php

..
</header>
<body>
@yield("content")
</body>
<footer>
..

contact.blade.php

@section('content')
@include('contact-content')
@stop

contact-content.blade.php

//contact

people.blade.php

@section('content')
@include('people-content')
@stop

people-content.blade.php

//people

home.blade.php

@extends('app')
@section('content')
//home
@include('people-content')
@include('contact-content')
@stop

@yield and @section problem while loading multiple sections in a single layout

I don't know if I understand you logic well. But seems like you misunderstood how @yield works.

Instead you can use @include like in this part of the documentation : https://laravel.com/docs/7.x/blade#including-subviews

I was thinking of something using the Aliasing Includes subpart a few scroll down from the main part I linked just above.

Tell me if it helped you

Yield multiple values

Because gen() returns a generator (a single item - so it can't be unpacked as two), it needs to be advanced first to get the values...

g = gen()
a, b = next(g)

It works with list because that implicitly consumes the generator.

Can we further make this a generator? Something like this:

g = gen();
def yield_g():
yield g.next();
k1,k2 = yield_g();

and therefore list(k1) would give [0,1,2,3,4] and list(k2) would give [1,2,3,4,5].

Keep your existing generator, and use izip (or zip):

from itertools import izip
k1, k2 = izip(*gen())

Multiple content_for on the same page

You should define your overwrite_content_for as the following (if I understand your question correctly):

  def overwrite_content_for(name, content = nil, &block)
content = capture(&block) if block_given?
@_content_for[name] = content if content
@_content_for[name] unless content
end

Note, that in case your block yields nil, then the old content will be retained. However, the whole idea doesn't sound good, as you're obviously doing some rendering (or at least object instantiation) twice.

How can I yield multiple pieces of content into an ember.js component template?

As of ember v1.10, yield accepts parameters. However handlebars doesn't yet allow for inline comparisons of variable values. By defining some properties on the component, we can get pretty close to what rails does.

Per the above example, the component's template would look like:

<header>{{yield header}}</header>
<div class="body">{{yield body}}</div>
<footer>{{yield footer}}</footer>

And the component definition would resolve the variable arguments to the yield statements:

export default Ember.Component.extend({
header: {isHeader: true},
footer: {isFooter: true},
body: {isBody: true}
});

This means that {{yield header}} is actually yielding an object {isHeader: true} to the consuming template. So we can use a nested if/else structure to declare the three sections like this:

{{#my-comp as |section|}}
{{#if section.isHeader}}
My header
{{else if section.isBody}}
My body
{{else if section.isFooter}}
My footer
{{/if}}
{{/my-comp}}


Related Topics



Leave a reply



Submit