master

laravel/framework

Last updated at: 29/12/2023 09:25

ManagesLayouts.php

TLDR

This file contains the ManagesLayouts trait which provides methods for managing sections and layouts in a view.

Methods

startSection($section, $content = null)

This method starts injecting content into a section. If content is null, it starts a new section. If content is not null, it extends an existing section with the specified content.

inject($section, $content)

This method is an alias of the startSection method and injects inline content into a section.

yieldSection()

This method stops injecting content into a section and returns its contents.

stopSection($overwrite = false)

This method stops injecting content into a section. If overwrite is true, it overwrites the section with the current output buffer contents. If overwrite is false, it extends the section with the current output buffer contents.

appendSection()

This method stops injecting content into a section, appends it to the section's existing content if any, and returns the section name.

extendSection($section, $content)

This protected method extends a section with the specified content. If the section already exists, it replaces the parent placeholder with the content.

yieldContent($section, $default = '')

This method gets the string contents of a section. If the section exists, it replaces the parent placeholder with an empty string and returns the section content. If the section does not exist, it returns the default value.

parentPlaceholder($section = '')

This static method gets the parent placeholder for the current request. If the parent placeholder does not exist for the section, it generates a new parent placeholder salt and stores it.

parentPlaceholderSalt()

This protected static method gets the parent placeholder salt. If the salt does not exist, it generates a random salt and stores it.

hasSection($name)

This method checks if a section with the specified name exists.

sectionMissing($name)

This method checks if a section with the specified name does not exist.

getSection($name, $default = null)

This method gets the contents of a section. If the section exists, it returns the section content. If the section does not exist, it returns the default value.

getSections()

This method gets the entire array of sections.

flushSections()

This method flushes all of the sections.

<?php

namespace Illuminate\View\Concerns;

use Illuminate\Contracts\View\View;
use Illuminate\Support\Str;
use InvalidArgumentException;

trait ManagesLayouts
{
    /**
     * All of the finished, captured sections.
     *
     * @var array
     */
    protected $sections = [];

    /**
     * The stack of in-progress sections.
     *
     * @var array
     */
    protected $sectionStack = [];

    /**
     * The parent placeholder for the request.
     *
     * @var mixed
     */
    protected static $parentPlaceholder = [];

    /**
     * The parent placeholder salt for the request.
     *
     * @var string
     */
    protected static $parentPlaceholderSalt;

    /**
     * Start injecting content into a section.
     *
     * @param  string  $section
     * @param  string|null  $content
     * @return void
     */
    public function startSection($section, $content = null)
    {
        if ($content === null) {
            if (ob_start()) {
                $this->sectionStack[] = $section;
            }
        } else {
            $this->extendSection($section, $content instanceof View ? $content : e($content));
        }
    }

    /**
     * Inject inline content into a section.
     *
     * @param  string  $section
     * @param  string  $content
     * @return void
     */
    public function inject($section, $content)
    {
        $this->startSection($section, $content);
    }

    /**
     * Stop injecting content into a section and return its contents.
     *
     * @return string
     */
    public function yieldSection()
    {
        if (empty($this->sectionStack)) {
            return '';
        }

        return $this->yieldContent($this->stopSection());
    }

    /**
     * Stop injecting content into a section.
     *
     * @param  bool  $overwrite
     * @return string
     *
     * @throws \InvalidArgumentException
     */
    public function stopSection($overwrite = false)
    {
        if (empty($this->sectionStack)) {
            throw new InvalidArgumentException('Cannot end a section without first starting one.');
        }

        $last = array_pop($this->sectionStack);

        if ($overwrite) {
            $this->sections[$last] = ob_get_clean();
        } else {
            $this->extendSection($last, ob_get_clean());
        }

        return $last;
    }

    /**
     * Stop injecting content into a section and append it.
     *
     * @return string
     *
     * @throws \InvalidArgumentException
     */
    public function appendSection()
    {
        if (empty($this->sectionStack)) {
            throw new InvalidArgumentException('Cannot end a section without first starting one.');
        }

        $last = array_pop($this->sectionStack);

        if (isset($this->sections[$last])) {
            $this->sections[$last] .= ob_get_clean();
        } else {
            $this->sections[$last] = ob_get_clean();
        }

        return $last;
    }

    /**
     * Append content to a given section.
     *
     * @param  string  $section
     * @param  string  $content
     * @return void
     */
    protected function extendSection($section, $content)
    {
        if (isset($this->sections[$section])) {
            $content = str_replace(static::parentPlaceholder($section), $content, $this->sections[$section]);
        }

        $this->sections[$section] = $content;
    }

    /**
     * Get the string contents of a section.
     *
     * @param  string  $section
     * @param  string  $default
     * @return string
     */
    public function yieldContent($section, $default = '')
    {
        $sectionContent = $default instanceof View ? $default : e($default);

        if (isset($this->sections[$section])) {
            $sectionContent = $this->sections[$section];
        }

        $sectionContent = str_replace('@@parent', '--parent--holder--', $sectionContent);

        return str_replace(
            '--parent--holder--', '@parent', str_replace(static::parentPlaceholder($section), '', $sectionContent)
        );
    }

    /**
     * Get the parent placeholder for the current request.
     *
     * @param  string  $section
     * @return string
     */
    public static function parentPlaceholder($section = '')
    {
        if (! isset(static::$parentPlaceholder[$section])) {
            $salt = static::parentPlaceholderSalt();

            static::$parentPlaceholder[$section] = '##parent-placeholder-'.hash('xxh128', $salt.$section).'##';
        }

        return static::$parentPlaceholder[$section];
    }

    /**
     * Get the parent placeholder salt.
     *
     * @return string
     */
    protected static function parentPlaceholderSalt()
    {
        if (! static::$parentPlaceholderSalt) {
            return static::$parentPlaceholderSalt = Str::random(40);
        }

        return static::$parentPlaceholderSalt;
    }

    /**
     * Check if section exists.
     *
     * @param  string  $name
     * @return bool
     */
    public function hasSection($name)
    {
        return array_key_exists($name, $this->sections);
    }

    /**
     * Check if section does not exist.
     *
     * @param  string  $name
     * @return bool
     */
    public function sectionMissing($name)
    {
        return ! $this->hasSection($name);
    }

    /**
     * Get the contents of a section.
     *
     * @param  string  $name
     * @param  string|null  $default
     * @return mixed
     */
    public function getSection($name, $default = null)
    {
        return $this->getSections()[$name] ?? $default;
    }

    /**
     * Get the entire array of sections.
     *
     * @return array
     */
    public function getSections()
    {
        return $this->sections;
    }

    /**
     * Flush all of the sections.
     *
     * @return void
     */
    public function flushSections()
    {
        $this->sections = [];
        $this->sectionStack = [];
    }
}