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';
}
Related
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>
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.
I am working on a project where i am allowing the user to change theme settings i.e colors, design etc from Admin Panel. I want the user to just enter the color hex code and that will change the linked properties in the view. What i tried to do is
In the view:
<style>
button.submitform:hover, button.submitform:focus{
background: {{ $customizer->global_lite_colorcode}} !important;
}
</style>
This solution work perfect but it has to be inline or in the html file, but i want to use externel css file.And this style i.e button.submitform lives in external css file called main.css . I want the laravel variable to change that property in there. How can i do this ?
I don't think that your css file main.css can parse notation of Laravel {{}}. Of course, if you must style pseudo classes like hover or focus, I have an idea about this, I think you can set a fixed style firstly:
button.submitform__red:hover, button.submitform__red:focus{
background: red !important;
}
And dynamically bind style with {{}} like this:
<button>
<div class="submitform__{{$customizer->global_lite_colorcode}}" />
</button>
js way:
document.querySelectorAll('.submitform__{{$customizer->global_lite_colorcode}}')[0].style['background'] = '{{$customizer->global_lite_colorcode}}';
Since you are dealing with a User (who is probably logged-in), you can very easily create CSS Styles based on the User-id and then load the style Dynamically in the view based on which user is logged-in.
STEP 1: USING USER ID TO CREATE A CSS FILE
<?php
// THIS IS AN ACTION IN YOUR CONTROLLER THAT HANDLES THE PROCESSING OF THE
// USER-SETTINGS FORM...
public function saveUserSetting(Request $request){
// OBTAIN THE $userID YOUR WAY...
$userDataPath = __DIR__ . "/../../../public/css/user_data";
// BUILD THE CSS TO BE ADDED TO USERS CUSTOM CSS FILE
// BASED ON HIS SETTINGS...
// $customizer = //<== GET THE $customizer OBJECT
$css = "button.submitform:hover, button.submitform:focus\{\n";
$css .= "background: " . $customizer->global_lite_colorcode . " !important;\n";
$css .= "\}\n"
// IF USER-SPECIFIC CSS FILE DOES NOT EXIST, WE CREATE IT,
// OTHERWISE WE JUST GET ITS CONTENT AND APPEND NEW STYLES TO IT..
if(!file_exists($userDataPath . "/user_{$userID}.css")){
file_put_contents($userDataPath . "/user_{$userID}.css", $css);
}else{
$data = file_get_contents($userDataPath . "/user_{$userID}.css");
if(!stristr($data, $css) ){$data.= $css;}
file_put_contents($userDataPath . "/user_{$userID}.css", $data);
}
// DO OTHER THINGS...
}
Then on the View, make sure you have created a section called "stylesheets" (for example) in your Master-File (That is; if you are using Template inheritance). Your Main Layout File would contain something like below within the < head > section.
#yield("stylesheets")
Then on the actual View File, you can dynamically add the User's Custom Style-Sheet based on the ID of the logged-in User like so:
#extends('layouts.app')
#section('stylesheets')
<link type="text/css" rel="stylesheet" media="all" href="{{ URL::asset('css/bootstrap.min.css') }}" />
<!-- THIS WILL LOAD ONLY THE USER'S CUSTOM CSS -->
<link type="text/css" rel="stylesheet" media="all" href="{{ URL::asset('css/user_data/user_' . $userID . ".css") }}" />
#endsection
However; it is important to note that in this approach, the data has to first be saved and written to File before you can see any changes... you wouldn't have an instant response of seeing your style applied immediately. If you need such Functionality, you may consider integrating Javascript.
Another way would be to gather all the Front-End Settings that the User specified in the Form, and store them as part of the users Table like under the column_name settings in either serialized or json_encoded format. This means that, once you fetch the Logged-in User Information, you can generate a CSS using the information stored in the settings....
This for sure can be done in an external file, but it won't be an external .css file; it will be a .blade.php file that contains any css styling, similar to the way you're doing it above. The issue is that since the property global_lite_colorcode is attached to a php variable $customizer, it cannot be parsed in a plain .css file.
On your view file, include a <style> tag the same way you are currently doing, and use the #include() blade command to pull in an external php file:
<style>
#include("views.custom.themes")
</style>
Specify a valid path to a .blade.php file using . notation, and in that file, include your "pseudo-inline" css:
button.submitform:hover, button.submitform:focus {
background: {{ $customizer->global_lite_colorcode}} !important;
}
<!-- Any other style tags that rely on php variables -->
As long as $customizer is accessible in the view file that calls the #include function, the code in the included file can also access it.
This is a bit of workaround to using an external .css file, but should work for your needs.
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
I started to learn CakePHP a few days ago, following their blog tutorial.
Now I am in the process of writing a small project for myself to get familiar with the framework.
Having studied their documentation, I noticed there are two ways to include CSS files.
One way is to echo the link tag(s) using the HtmlHelper: echo $this->Html->css(array('style', 'forms', 'modal'));. That type of linking is referred to as 'inline style' according to the options array.
The other method is to add the tags to the (I believe default?) CSS block and then print that block inside the <head>:
echo $this->Html->css(array('style', 'forms', 'modal'), array('inline' => false));
echo $this->fetch('css');
What are the advantages of using one way over the other?
Consider the following layout file:
...
<head>
...
<?= $this->Html->css('main.css'); ?>
<?= $this->fetch('css'); ?>
...
</head>
...
The simplest way
By default the rendered view would contain:
...
<head>
...
<link rel="stylesheet" type="text/css" href="/css/main.css" />
</head>
If there is no logic associated with whether a css file should be added - it's appropriate to simply edit the layout file and add the css file, ignoring the inline property.
Advantage: It's simple, clear and obvious what's happening
The Dynamic way
If however there is logic associated with whether a particular css file should be included - this is where the inline property becomes useful.
Consider the following view file:
<?php
if ($something) {
$this->Html->css('maps.css', ['inline' => false]);
echo $this->element('maps');
}
?>
View contents
Or a plugin which includes the following helper:
<?php
class AwesomeHelper extends AppHelper {
public function beforeLayout() {
$this->Html->css('awesome.css', ['inline' => false]);
$this->Html->js('awesome.js', ['inline' => false]); // also applies to js files
}
}
In these cases without using the inline property or editing the layout file, it's not possible to add the css files to the head of the rendered output. However by using the inline property, it is possible to build up the css files required for the final view.
Advantage: Code outside the layout file can add required css files to the output in the head.