Git Product home page Git Product logo

laravel-view-components's Introduction

THIS PACKAGE HAS BEEN ABANDONED

A better way to connect data with view rendering in Laravel

Latest Version on Packagist GitHub Workflow Status StyleCI Quality Score Total Downloads

View components are a way to help organize logic tied to view, similar to view composers.

namespace App\Http\ViewComponents;

use Illuminate\Http\Request;
use Illuminate\Contracts\Support\Htmlable;

class NavigationComponent implements Htmlable
{
    /** \Illuminate\Http\Request */
    private $request;

    /** @var string */
    private $backgroundColor;

    public function __construct(Request $request, string $backgroundColor)
    {
        $this->request = $request;
        $this->backgroundColor = $backgroundColor;
    }

    public function toHtml(): string
    {
        return view('components.navigation', [
            'activeUrl' => $this->request->url(),
            'backgroundColor' => $this->backgroundColor,
        ]);
    }
}
@render('navigationComponent', ['backgroundColor' => 'black'])

A view component can be anything that implements Laravel's Htmlable contract, so you don't necessarily need to use Blade views to render the component. This is useful for wrapping third party HTML packages, like spatie/laravel-menu.

namespace App\Http\ViewComponents;

use Illuminate\Contracts\Support\Htmlable;
use Illuminate\Contracts\Auth\Guard;
use Spatie\Menu\Laravel\Menu;

class MainMenuComponent implements Htmlable
{
    /** @var \Illuminate\Contracts\Auth\Guard */
    private $guard;

    /** @var string */
    private $class;

    public function __construct(Guard $guard, string $class = null)
    {
        $this->guard = $guard;
        $this->class = $class;
    }

    public function toHtml(): string
    {
        $menu = Menu::new()
            ->addClass($this->class)
            ->url('/', 'Home')
            ->url('/projects', 'Projects');

        if ($this->guard->check()) {
            $menu->url('/admin', 'Adminland');
        }

        return $menu;
    }
}
@render('mainMenuComponent', ['class' => 'background-green'])

The benefit over view composers is that data and rendering logic are explicitly tied together in components instead of being connected afterwards. They also allow you to seamlessly combine properties and dependency injection.

This package is based on Introducing View Components in Laravel, an alternative to View Composers by Jeff Ochoa.

Support us

We invest a lot of resources into creating best in class open source packages. You can support us by buying one of our paid products.

We highly appreciate you sending us a postcard from your hometown, mentioning which of our package(s) you are using. You'll find our address on our contact page. We publish all received postcards on our virtual postcard wall.

Installation

You can install the package via composer:

composer require spatie/laravel-view-components

No additional setup necessary. Laravel will automatically discover and register the service provider.

Optionally you can publish the config file with:

php artisan vendor:publish --provider="Spatie\ViewComponents\ViewComponentsServiceProvider" --tag="config"

This is the default content of the file that will be published at config/view-components:

return [
    /*
     * The root namespace where components reside. Components can be referenced
     * with camelCase & dot notation.
     *
     * Example: 'root_namespace' => App\Http\ViewComponents::class
     *
     * `@render('myComponent')
     *     => `App\Http\ViewComponents\MyComponent`
     */
    'root_namespace' => 'App\Http\ViewComponents',

    /*
     * Register alternative namespaces here, similar to custom view paths.
     *
     * Example: 'navigation' => App\Services\Navigation::class,
     *
     * `@render('navigation::mainMenu')`
     *     => `App\Services\Navigation\MainMenu`
     */
    'namespaces' => [
        // 'navigation' => App\Services\Navigation::class,
    ],
];

Usage

The @render directive

The @render Blade directive accepts two arguments: the first is the view component's path or class name, the second is an extra set of properties (optional).

You can choose between referencing the component via a path or a class name.

@render('myComponent')
@render(App\Http\ViewComponents\MyComponent::class)

Parameters will be injected in the view components __construct method. The component is instantiated with Laravel's container, so parameters that aren't provided by render will be automatically injected.

use Illuminate\Http\Request;

class MyComponent implements Htmlable
{
    public function __construct(Request $request, string $color)
    {
        $this->request = $request;
        $this->color = $color;
    }

    // ...
}
@render('myComponent', ['color' => 'red'])

In the above example, $color is explicitly set, and a $request object will be injected by Laravel.

Configuration

The root namespace

By configuring root_namespace, you can define where the bulk of your view components are located. By default, this is in App\Http\ViewComponents.

app/
  Http/
    ViewComponents/
      MyComponent.php
      Nested/
        NestedComponent.php

The above components can be rendered with @render('myComponent') and @render('nested.nestedComponent').

Additional namespaces

You can register additional namespaces in the namespaces configuration, similar to view paths.

return [
    'namespaces' => [
        'navigation' => App\Services\Navigation::class,
    ],
];
app/
  Services/
    Navigation/
      Menu.php

The above Menu component can now be rendered with @render('navigation::menu').

Testing

composer test

Changelog

Please see CHANGELOG for more information on what has changed recently.

Contributing

Please see CONTRIBUTING for details.

Security

If you discover any security related issues, please email [email protected] instead of using the issue tracker.

Credits

License

The MIT License (MIT). Please see License File for more information.

laravel-view-components's People

Contributors

adamlehmann avatar akoepcke avatar clarkewing avatar dunice avatar freekmurze avatar jmlallier avatar julesjanssen avatar robgordijn avatar sebastiandedeyne avatar thewebartisan7 avatar tvbeek avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar

laravel-view-components's Issues

How do you use view components for components with html content?

Hi,

I have a Box component that end up using like this:

@render('Box', [
            'title' => __('Verify Your Email Address'),
            'content' =>
                __('Before proceeding, please check your email for a verification link.') .
                __('If you did not receive the email') .
                " <a href='{route('verification.resend')}'>".__('click here to request another')."</a>"
            ])

There are many things I find anoying here, but the one I dislike the most is having to use {!! !!} inside the component template.

#8 Slots whould be a great solution for this. But as they're not currently supported I suspect you guys achieve this in another way.

I was thinking about doing an "HtmlSafe" component and render my box like:

@render('Box', [
            'title' => __('Verify Your Email Address'),
            'content' => new HtmlSafe([
                    __('Before proceeding, please check your email for a verification link.'),
                    __('If you did not receive the email'),
                    " <a href='{route('verification.resend')}'>".__('click here to request another')."</a>"
                 ])
            ])

And do some check to see if I have to scape my content or not, of course this end up being really verbose. Any advice it's appreciated here :)

Package does not publish config file

Hi. The package is working ok but the configuration file is not published.

php artisan vendor:publish --provider="Spatie\ViewComponents\ViewComponentsServiceProvider" --tag="config" only outputs Publishing complete. and php artisan vendor:publish does not show the package.
vendor_publish

As a workaround, I've just copied manually the configuration file to the app config folder.

Cheers

@render in html after upgrade from 1.2.0 to 1.3.0

After upgrading from 1.2.0 to 1.3.0
I see the @render tags in the html instead of the component result.

If I revert the change from #19 it work as expected.

I'm not sure what the reason is for the pull request. I can create a PR to undo that change if wanted. Else we need to debug why it is needed and didn't work.

Support slots

Is possible to support slot like below?

@render('buttonComponent', ['backgroundColor' => 'black'])
Button Text
@endrender

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.