Laravel - js sections of different blade files making conflict - php

I have two blade file and both of them has js section. But in the browser, shows only comments js files not single. I need to use both js files.
Here are blade files in a nutshell
comments.blade
// php and html codes
#section("js")
// js codes of comments blade
#endsection
single.blade
#extends("master")
#section("content")
// html and php codes
#include("comments")
#endsection
#section("js")
// js codes of single blade
#endsection
Why there are conflict between two blade file ? And how do I fix it ?

You can use #append:
comments.blade
// php and html codes
#section("js")
// js codes of comments blade
#append
single.blade
#extends("master")
#section("content")
// html and php codes
#include("comments")
#endsection
#section("js")
// js codes of single blade
#append
I would recommend to use #stack though:
From the docs:
Blade allows you to push to named stacks which can be rendered
somewhere else in another view or layout. This can be particularly
useful for specifying any JavaScript libraries required by your child
views:
#push('scripts')
<script src="/example.js"></script>
#endpush
You may push to a stack as many times as needed. To render the
complete stack contents, pass the name of the stack to the #stack
directive:
<head>
<!-- Head Contents -->
#stack('scripts')
</head>

Related

Using Laravel bootstrap css to style only a section of a page

I'm trying to use the default bootstrap css (app.css) that ships with Laravel to style a section of my page - specifically, the form section of my registration page.
I don't want to include app.css in my html header as it gives me undesired effect on other parts of the page. So I want it to style only my html forms within the page.
Currently, I've used either the asset() or HTML::style() methods like this within my form section:
#section('form')
<style> #import "{{ asset('css/app.css') }}"; </style>
<form>...</form>
#endsection
OR
#section('form')
{{ HTML::style('css/app.css') }}
<form>...</form>
#endsection
Both method loads the style correctly, but affects the entire page instead of only the form elements.
I tried using the ViewComposer class to solve this problem by setting a variable in ViewComposer to my desired style - returning it only when I request the required view:
class ViewComposer
{
public function compose(View $view)
{
$data = [];
switch($view->getName())
{
...
case 'sections.register':
$this->data = ['style'=>"<style> #import \"". asset('css/app.css') . "\"; </style>"];
break;
}
return $view->with($this->data);
}
}
However, when I render the sections.register sub-view, I get the style variable like this:
#section('form')
{{ $style ?? '' }}
<form>...</form>
#endsection
the output on the browser is not parsed as css but displayed as-is:
<style> #import "{{ asset('css/app.css') }}"; </style>
So, is there a way I can parse external css for only a given view section within the html page and can it be achieved using the ViewComposer class?
UPDATE:
I was trying a few things and used this:
#section('form')
{!! $style ?? '' !!}
<form>...</form>
#endsection
The css is parsed but still applied to the entire page. I still need it applied to only the form section.
1. One option is to copy only the css you need and paste it into custom css and make a different layout for that view. But that can be tedious work as you said.
2. Another option is to prefix you app.css file. There is a software that can do that here is the tutorial. So if you prefix whole css file with for example: .laravel-app then you can wrap anything that you would like to be styled by app.css like this:
<div class="laravel-app">
<!-- Everything in here will be styled by app.css -->
</div>
This will help you in the long run with your project.
First of all, importing or loading css per-view will be bad for the performance of the application. So, using View Composer to load in css is not advisable. I took a cue from Denis Ćerić's answer, though it wasn't clear at first glance.
Also, the accepted answer on this post made things a little clearer.
The right way to achieve this is to use a css preprocessor. Popular ones are less and sass. I used sass because it is currently adopted by Laravel.
I installed sass on my windows machine following the instructions here.
Create a new scss file: app-custom.scss in the same folder as app.css.
Modify app-custom.scss using nested imports:
.app-form
{
#import 'app';
}
Generate app-custom.css using the sass command on Windows command line:
sass app-custom.scss app-custom.css
Change the class of your form to app-form:
#section('form')
<form class='app-form'>...</form>
#endsection
Include app-custom.css in your header using link tag:
<head>
<link href="{{ asset('css/app-custom.css') }}" rel="stylesheet">
</head>
and you are done.
HINT: if you want to use the style in app.css for multiple separate sections of your page, you can still achieve this from a single scss file. Just include the classes of each section in your scss file like this:
.section-1, .section-2, .section-3
{
#import 'app';
}

How do I ONLY include a jQuery function when a Blade contains a certain #include View?

I am trying to make an #if-statement to only display a certain jQuery DataTable function if a certain Blade file has been #included into a show blade.
This might sound like making it harder than it is, but I want to keep the #section('scripts') area clean if it is not necessary to use it within the current show-page.
Placing the <script> within the #include did NOT work;
Placing the <script> within the show-page did work, but makes the show-page bloated; and
The current code (see below), only checks if the view exists so it will always be TRUE.
#if ( View::exists('admin.users') ) {{-- on the current Blade! --}}
$('#usersTable').DataTable({
"language": #json(__('datatables')),
});
#endif
I've encountered a similar issue myself. To solve it you can make use of blade stacks.
The way I do it is in the footer of my main layout, below the script tags including the js I put #stack('javascript'). Then, in a view where I want to include some js, so for you this would be in the admin.users view I would add..
#push('javascript')
<script>
// my js here
</script>
#endpush
That way the js will be appended to the footer once the view is included.
For more information see the docs.

How to call ...blade.php in different folder inside views folder in laravel

Excuse me, i would like to ask about how to call another page blade in different subfolder inside views.
Example :
views
--home(subfolder)
--beranda(subfolder)
--refresh.blade.php
--layouts(subfolder)
--master.blade.php
in master.blade.php implements template page, when i click one link in this folder may have to go in refresh.blade.php.
Likely another web layout, they have a lot of link in header like 'Home', 'Paper', etc.
I'm still learned more about laravel as beginner practice.
May you can help me, i'll appreciate that.
Regard, Aga.
I think you can refer to some directives such as #include and #extends in the laravel blade.
For example, in the admin.common.header view (located at admin/common/header.blade.php), we have some basic page code (common to various pages such as navigation bar or layout). We use #yield such as #yield ("extra_js") or #yield ("extra_css") where we want to add code later.
header.blade.php
<html>
<head>
something maybe ...
#yield("extra_css")
</head>
<body>
something maybe ...
#yield("extra_js")
</body>
</html>
And in another view such as admin.feedback.feedback, you can use #extends('admin.common.header') at the top of the code to inheritance the template and you will get the layout of this template.
For different content in the feedback template, you can use #section to give you code to fill in the inheritance template such as #section('extra_js').
feedback.blade.php
#extends('admin.common.header')
#section('extra_js')
<script> something... </script>
#endsection
If you want to include one blade, just use #include.
<div>
#include('shared.errors')
<form>
<!-- Form Contents -->
</form>
</div>
In laravel blade there are many instructions to complete the rendering of the template, if you want to know clearly, please refer to the corresponding version of the official document.

Add static page into CMS

I use laravel 5 with blade template engine. I want to create module to insert static pages as .zip archive which contains html, css, js and image files into my CMS. This should be helpful when user need create page with another company and don't have skills in laravel or dont need to know our project structure.
My current process looks like:
prepare .zip archive with structure:
assets
js
css
images
index.html
Scenario:
Open CMS and fill title, link (slug), category and put archive into file input. On save I unzip archive into public/static_pages/__slug__/ and replace index.html links for resources (css, js, images) by prepend correct link. Link for this page look like /page/{category_slug}/{slug}
Cases:
That works, but sometimes I want to use layout e.g some pages use menu and footer, but other not. What should I do then?
I have some ideas:
convert html file into blade. During development we will add special
comments like <!-- section content -->, <!-- section menu --> and
convert it into blade template.
add correct blade file
add html and chose layout in CMS. If layout was chosen then use it and add into #section('content') our static page, if not - show static page without layout.
add html file with comments like <!-- insert menu -->, <!-- insert content -->. We should prepare some 'sections' in database or files and replace comments by prepared sections.
Problems:
In all cases I no have idea what about add css / js files in correct places (in html).
In case with layout - if we use layout, then we should have predefined jquery. So in static page we couldnt duplicate it, but during development we need it.
In case without layout - add every time jquery and global css inside archive, so we duplicate it on the server and can't cache it.
What I should do?
if you don't want to use the Less/Sass or task runner such as gulp you can manually add your assets files to the public folder :
public
|_css
|_js
in your views just simply link it to them as below:
{{ HTML::style('css/style.css') }}
Or
<link media="all" type="text/css" rel="stylesheet" href="css/style.css">
same for the scripts. you can get more information from here:
http://laravel.com/docs/5.1/blade
http://laravel.com/docs/5.0/templates
i try to organize my theme files with a folder in my view named
" layout"
then make the following files :
master.blade.php, header.blade.php ,footer.blade.php
set you html header codes in header.blade.php and same for foooter you can set your master like this:
<!DOCTYPE html>
<html>
<head>
<title>#yield('title')</title>
#include('layout.header')
</head>
<body>
#yield('content')
</body>
<footer>
#include('layout.footer')
</footer>
</html>
then in any of your view the blade files just write:
#extends('layout.master')
#section('title','title of your page')
#section('content')
your body content
#stop

Having Mustache templates both render and not, with Laravel/Blade and JavaScript

I'm using Laravel and all my templates are using Blade templating. There are a few parts of pages which need to be rendered both on the server side and by JavaScript. For these I'm using Mustache templates (with mustache-l4).
The problem is how to have Laravel render the templates, but also to include them in the page with the Mustache tags intact, for the JS to pick up.
For example, if I have a (simplified example) Blade template like this:
<html>
<head></head>
<body>
<h1>{{ $pageTitle }}</h1>
#include('partials/'.$partialName, array('some_text' => $pageText))
<script type="text/mustache">
#include('partials/'.$partialName)
</script>
</body>
</html>
which includes .mustache partials like this:
{{#some_text}}
<p>{{some_text}}</p>
{{/some_text}}
The Mustache partial is rendered on page load fine. BUT when it's included between the <script></script> tags I want it to be rendered verbatim. ie, the {{#some_text}} Mustache tags should be there in the rendered HTML. Then the JavaScript can read it in as a Mustache template.
I can see this might be possible by changing the tag delimiters on the server-side (Blade) templates but at this stage, with scores of Blade templates already working, I'd rather not.
I can't get my head round how to do this. Could I change the Mustache delimiters just for one of the times it's included, so it's only fully rendered then?
Another way would be to escape the tags with #
<div>#{{ $str }}</div>
<div>#{{"<a>Plain text</a>"}}</div>
will result in
<div>{{ $str }}</div>
<div>{{"<a>Plain text</a>"}}</div>
StackOverflow Answer
One way of doing this would be to change blade's content tag.
Like so :
Blade::setContentTags('[%', '%]');
So that {{}} tags will be considered as plain string.
For further information refer this snippet:
laravel-recipes

Categories