Denis Sheremet
Denis Sheremet

Reputation: 2583

Laravel 5 proper way to require CSS file from view

I've got specific Form component, which is declared as

Form::component('fcRadio', 'components.form.fcradio', ['name', 'options', 'selected' => null]);

and used as

{{ Form::fcRadio('name', $options }}

What I want is somehow attach custom CSS file, so if the page fires this component at least once, the desired CSS file is included to the <head> of my document.

For example, in Joomla it was like

$this->document->addStylesheet('my_awesome_style.css');

Is there any way to achieve the same in Laravel?

UPD:

I've extended the answers below a bit to let it add multiple styles from multiple templates. Finally, it looks like this:

@section('styles')
@parent
{{HTML::style('css/fcradio.css')}}
@stop

It works fine, but if I use the component twice per page, style is also adds twice. How can I allow multiple but unique entries?

Upvotes: 0

Views: 14369

Answers (3)

Denis Sheremet
Denis Sheremet

Reputation: 2583

I've finally found a bit tricky but working solution:

@hasSection('fcRadioStyle')
@else

@section('fcRadioStyle')
{{Html::style('css/components/fcradio.css')}}
@stop

@section('styles')
@yield('fcRadioStyle')
@append

@endif

This makes by Form::fcRadio append this style only once

Upvotes: 0

Mark
Mark

Reputation: 1376

So this is typically how I deal with it:

In your folder: resources/views I create a folder called layout. This folder handles the templates for all my pages.

Then I create a file called default.blade.php. In it I put the bulk of the HTML code. Here's an example of how default.blade.php could look (slimmed down, obviously)

    <!DOCTYPE html>
    <html lang="en">
    <head>
      <meta charset="utf-8">
      <meta http-equiv="x-ua-compatible" content="ie=edge">
      <meta name="viewport" content="width=device-width, initial-scale=1">

      <title>
      @yield('title')
      </title>

      <link rel="stylesheet" href="{{ asset('css/main.css') }}">

      <!-- Additional per-page css -->
      @yield('css')
    </head>

    <body>

      @yield('content')

      <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.4/jquery.min.js"></script>
      <script src="js/script.js"></script>
      <script src="{{ asset('js/bootstrap.min.js') }}"></script>

      <!-- Include per-page JS -->
      @yield('js')
    </body>

    </html>

Right, so essentially what we have so far is the @yield() and asset() helpers.

@yield() is special blade syntax that Laravel uses to say, "Okay. Any time a blade view that is inheriting THIS master template calls the section named in this @yield() I will display that content right here.

asset() is a nifty little helper that basically appends your URL structure onto the string you pass it. So if your url is http://MyGreatSite.com and you use asset('js/script.js') it will spit out a fully qualified URL that will work anywhere on the site (http://MyGreatSite.com/js/script.js). asset() is great because you can use it in blade templates that will get sent out as an email and all of the files will work in an email inbox because they are absolute links.

Right. So now we have this master template and we need to use it. So what I do is create another view in the resources/views directory. Lets say we're doing a contact page. I would make contact.blade.php. Now I want to inherit that master template we created. So we do that like so:

    @extends('layout.default)

    @section('css')
    <link rel="stylesheet" href="{{ asset('css/contact.css') }}">
    @stop


    @section('title')

    Contact Us

    @stop


    @section('content')

    <h1>Contact us</h1>

    <p>
    Contact us via email: <a href="mailto:[email protected]">[email protected]</a>
    </p>

    @stop


    @section('js')

    <script src="{{ asset('js/contact-form.js') }}"></script>

    @stop

Okay, so, first things first. At the very top we tell this blade file that we want to use the template we just made. We use the blade helper @extends() and pass it the path to our view relative to the views directory separated by periods.

Next, we want to create the sections that correspond to the template. We do that by opening the section with @section() and passing the name of the section we want to push this block of content to. We write our content and then we close the section by using @stop. Pretty simple. For images, css, or js, we simply use the asset() helper again.

I know it's a little long-winded, but hopefully that helps and explains the process a little better.

tl;dr: Use @yield(), @section(), and asset().

Upvotes: 4

Dave3of5
Dave3of5

Reputation: 730

So I think I understand what you are saying.

In your blade layout file create a section inside the head:

<head>
    @yield('componentcss')
</head>

And in the component do:

@section('componentcss')
{{HTML::style('css/fcradio.css')}}
@stop

You could also just include the css but I wouldn't advise this:

@section('componentcss')
<style>
    .exampleclass {text-align:center;}
</style>
@stop

Hopefully I have understood you correctly.

Upvotes: 1

Related Questions