How to add css class to body tag in layout in yii2? - yii2

I want to add css class to body tag in yii2 advanced in frontend/views/layouts/main.php how can I do it?

You can do this dynamically like this:
<body class="<?= $this->context->bodyClass; ?>">
And in main Controller (all other controllers should extend this Controller) define property:
public $bodyClass;
or for default value:
public $bodyClass = 'custom-skin';
Ofc you can override this property in any extending controller by redefining it:
public $bodyClass = 'custom-skin-2';
In init:
public function init() {
parent::init();
$this->bodyClass = 'custom-skin-2';
}
In specific action:
public function actionView()
{
$this->bodyClass = 'custom-skin-3';
return $this->render('view');
}

You add your class simply to body tag
<body class="yourClass">

Another possible solution would be using the variable $params in your view.
Example
In your view you can define:
$this->params['bodyClass'] = 'yourclass';
And then, in your layout file, you'd go:
[.. head and other codes ..]
<body <? if(isset($this->params['bodyClass'])) echo 'class="' . $this->params['bodyClass'] . '"'; ?>>
<?php $this->beginBody() ?>
[.. rest of your code ..]
Notice that
I'm suggesting you to use the if so it only puts the class if it the $params['bodyClass'] is set in your view.
Also, you can use whatever name you want in the place of bodyClass.
This example will output <body class="yourclass">
Cheers.

Related

Yii2 add to head() and endBody()

In developing a site that can have multiple front-end themes, I am looking for a way to allow users on the back-end to manually inject code into the head and body. Two use cases are as follows:
Case 1 - Styles
In the back-end, the user selects a theme.
User likes the theme but would like to make links a different color.
Rather than copy and modify the theme, user can set custom code to execute at end of <head> tag.
Case 2 - Scripts
User wants to add custom JavaScript to end of document but requires an additional JavaScript library as well.
Rather than copy and modify the theme, user can set custom code to execute at and of <body> tag.
I understand that both of these specific cases could be accomplished (in part) with the use of registerCss and registerJs but those automatically wrap whatever is passed to them in <style> or <script> tags. I am hoping there is a way to just directly inject whatever is indicated directly into the head() or endBody() methods. The reason behind this is that I do not wish to limit what the user can inject (perhaps a script tag is needed in the head).
Currently, I am just storing the code-to-be-added in params then manually including them in each theme as follows:
<?php $this->endBody() ?>
<?= $this->params['theme_include_body_end'] ?>
This is undesirable as it can easily be forgotten when creating the theme. I would like to find a way to append my param value to the endBody() call automatically so whenever endBody() is called, my code is included (same for the head() call).
Yii2 already provide this functionality in View Class by using Block Widget
you need 2 simple steps:
1- (in required View file): in any given view
<?php $this->beginBlock('block1'); ?>
...content of block1...
<?php $this->endBlock(); ?>
...
<?php $this->beginBlock('block3'); ?>
...content of block3...
<?php $this->endBlock(); ?>
2- (in layout): define block name and its place in the layout page
...
<?php if (isset($this->blocks['block1'])): ?>
<?= $this->blocks['block1'] ?>
<?php else: ?>
... default content for block1 ...
<?php endif; ?>
...
<?php if (isset($this->blocks['block2'])): ?>
<?= $this->blocks['block2'] ?>
<?php else: ?>
... default content for block2 ...
<?php endif; ?>
...
<?php if (isset($this->blocks['block3'])): ?>
<?= $this->blocks['block3'] ?>
<?php else: ?>
... default content for block3 ...
<?php endif; ?>
...
Referance: Yii2 Guide
http://www.yiiframework.com/doc-2.0/guide-structure-views.html#using-blocks
I hope this will help someone. Thank you.
You can use own View component that overrides methods renderHeadHtml() and renderBodyEndHtml(). In these methods can be injected necessary code as you need:
namespace common/components;
class View extends \yii\web\View {
/**
* #var string Content that should be injected to end of `<head>` tag
*/
public $injectToHead = '';
/**
* #var string Content that should be injected to end of `<body>` tag
*/
public $injectToBodyEnd = '';
/**
* #inheritdoc
*/
protected function renderHeadHtml()
{
return parent::renderHeadHtml() . $this->injectToHead;
}
/**
* #inheritdoc
*/
protected function renderBodyEndHtml($ajaxMode)
{
return parent::renderBodyEndHtml(ajaxMode) . $this->injectToBodyEnd;
}
}
In config file:
// ...
'components' => [
// ...
'view' => [
'class' => '\common\components\View',
]
]
Somewhere in controller code:
\Yii::$app->view->injectToHead = '...';
\Yii::$app->view->injectToBodyEnd = '...';
Another, perhaps more simple alternative depending on your use case is to use the view events. You can inject different items at different parts of the page. For example:
Yii::$app->view->on(View::EVENT_END_BODY, function () {
echo date('Y-m-d');
});
You can read more here: https://www.yiiframework.com/doc/guide/2.0/en/structure-views#view-events

How to generate radio button with label tag completely outside input tag in yii2

Yii2 HTML::radio() helper generate html input tag with label tag around that input like this:
<label>
<input type="radio" name="abc" value="1"> Hello
</label>
But I need it like this:
<input type="radio" name="abc" value="1" id="radio1">
<label for "radio1">Hello</label>
Is it postible to custozime this inside radio helper ?
No, you can't. As you can see from yii\helper\BaseHtml class code, this nesting of tags comes from the source code of radio() method, without means of configuration by changing options.
What you need is override that method. It's really easy.
In the namespace app\helpers, create class Html. Put it into a new file named /Helpers/Html.php relative to your app root (if you've got Yii basic app), and put something like this inside:
namespace app\helpers;
use Yii;
use yii\helpers\BaseHtml;
class Html extends BaseHtml
{
public static function radio($name, $checked = false, $options = [])
{
$options['checked'] = (bool) $checked;
$value = array_key_exists('value', $options) ? $options['value'] : '1';
if (isset($options['uncheck'])) {
// add a hidden field so that if the radio button is not selected, it still submits a value
$hidden = static::hiddenInput($name, $options['uncheck']);
unset($options['uncheck']);
} else {
$hidden = '';
}
if (isset($options['label'])) {
$label = $options['label'];
$labelOptions = isset($options['labelOptions']) ? $options['labelOptions'] : [];
unset($options['label'], $options['labelOptions']);
$content = static::input('radio', $name, $value, $options);
$content .= static::label($label, null, $labelOptions);
return $hidden . $content;
} else {
return $hidden . static::input('radio', $name, $value, $options);
}
}
}
Explanation:
We've just copied the code of radio() method from yii\helpers\BaseHtml and changed the lines containing static::label() to separate output of static::input() from it;
Since both original and our custom classes extend yii\helpers\BaseHtml, and original yii\helpers\Html is not redefining none of BaseHtml methods, there will be no loss in logic for elements other than radio.
Namespace and class name shouldn't be exactly the same, but obviously they should just differ from yii\helpers\Html.
Just replace use yii\helpers\Html; with use app\helpers\Html; in your View code.
That's all!

how to pass values from controller to layout file in yii2

I'm trying to pass a variable value from controller to my main.php layout file but i keep getting error Undefined variable: contentWrapperBackground. below is my code
controller
public function actionList()
{
$contentWrapperBackground = "ff4400;";
$contentBackground = "3c8dbc;";
return $this->render('list', [
'contentWrapperBackground' =>$contentWrapperBackground,
'contentBackground' => $contentBackground,
]);
}
and in my layout file like this
<div class="content-wrapper" style="background-color:#<?=$contentWrapperBackground?>">
<!-- Content Header (Page header) -->
<!-- Main content -->
<section class="content" style="background-color:#<?=$contentBackground?>">
but i always get error Undefined variable: contentWrapperBackground. I'm trying to change the background color of for different pages. any help on this, and am also open to another idea on how to make this work thanks
don't use session for this!
Simple solution:
class Controller extends \yii\web\Controller
{
$public $contentWrapperBackground;
$public $contentBackground;
}
class YourController extends Controller
{
public function actionList()
{
$this->contentWrapperBackground = "ff4400;";
$this->contentBackground = "3c8dbc;";
return $this->render('list', []);
}
}
in your main layout
<div class="content-wrapper" style="background-color:#<?=Yii::$app->controller->contentWrapperBackground?>">
or another option
<div class="content-wrapper" style="background-color:#<?=$this->context->contentWrapperBackground?>">
you can set param in controller
Yii::$app->view->params['paramName'] = 'data';
get data in layout
$this->params['paramName'];

Add styling to all #Html.ActionLink from css class

I know I am able to add a class to a #Html.Actionlink by using, which acts on a single Actionlink at a time:
#Html.ActionLink("Add",
"UpdateNote",
"Notes",
new { id = 0, type = (int)THOS.Utilities.Enumerations.Enumerations.Note.RelatedApplicationType.Law, appid = ((ObjectModelLibrary.Law)ViewData["currentLaw"]).LawID, baseappid = ((ObjectModelLibrary.Law)ViewData["currentLaw"]).LawID }
new { #class = "btn btn-primary icon-edit"},
null)
However,
Is there a way of defining a class (much like adding a style to all divs in the css file like:
div{
color: red;
}
^ ^
| |
this way will act on *all* divs
instead of going
<div class="myClass"></div>
I can just write:
<div></div>
which will automatically have color:red included
would there be a way of defining a class for an ActionLink without going to each actionlink and typing #Class="myClass"
For Example
for adding styling for all button instances:
input[type="button"]{
background-color:red;
}
Can i do this with something like:
input[type="actionlink"]{
//styles for all actionlinks in project
}
and so all actionlinks can be written as:
#Html.ActionLink("Action","Controller")
and automatically include the styling stated in my css file?
I would do this the first way, but i've already ~100 made without defining a class, and don't fancy copy and pasting:
class="myClass"
ActionLink generates just normal anchors, so you can write:
a{
color:red;
}
But to get just ActionLinks you will need to call them by a class or a container.
Also may be a better way to do it is to create a custom ActionLink and put a default class inside and using this class you can do your selector, like this you will use this new Custom ActionLink and no need to copy paste classes.
public static class LinkExtensions
{
public static MvcHtmlString MyActionLink(
this HtmlHelper htmlHelper,
string linkText,
string action,
string controller
)
{
var currentAction = htmlHelper.ViewContext.RouteData.GetRequiredString("action");
var currentController = htmlHelper.ViewContext.RouteData.GetRequiredString("controller");
if (action == currentAction && controller == currentController)
{
var anchor = new TagBuilder("a");
anchor.Attributes["href"] = "#";
anchor.AddCssClass("currentPageCSS");
anchor.SetInnerText(linkText);
return MvcHtmlString.Create(anchor.ToString());
}
return htmlHelper.ActionLink(linkText, action, controller);
}
}
%= Html.MyActionLink("hello foo", "Index", "Home") %>
<%= Html.MyActionLink("hello bar", "About", "Home") %>
Code copied from https://stackoverflow.com/a/5084672/20126

Twig and CodeIgniter form rendering issue. Form is being displayed as a String and not the HTML form

My first time to use Twig template with CodeIgniter. I'm used to the default form functionality of the framework, but I was asked to try to render the form using Twig. I find the template engine to be nice and confusing at the same time. So that means, my controller would be very fat with code. But the main issue here is to render the form using twig.
Below is what I used to do when I want to render a form. View: TableSample.php
<?php
echo form_open("", array("name"=>"form_reg", "method"=>"post", "id"=>"form_reg"));
echo form_input("type"=>"text", "name"=>"fname", "value"=>set_value("fname"));
echo form_input("type"=>"text", "name"=>"lname", "value"=>set_value("lname"));
echo form_input("type"=>"text", "name"=>"emailaddress", "value"=>set_value("emailaddress"));
echo form_input("type"=>"submit", "name"=>"submit", "value"=>"Submit");
echo form_close();
?>
Controller: register.php
public function register (){
$this->load->view("TableSample");
if($this->input->post("submit")) {
/** retrieve input details, pass them as array to model, then redirect if registration is successful**/
}
}
But since I have to use Twig, things have been a little bit different.
public function register () {
$detail["form_open"] = form_open("", array("name"=>"form_reg", "method"=>"post", "id"=>"form_reg"));
$detail["form_input_name"] = form_input("type"=>"text", "name"=>"fname");
$detail["form_input_lname"] = form_input("type"=>"text", "name"=>"lname");
$detail["form_input_eadd"] = form_input("type"=>"text", "name"=>"email");
$detail["form_input_submit"] = form_input("type"=>"submit", "name"=>"submit", "value"=>"Submit");
$detail["form_close"] = form_close();
//codes for saving here
//call twig view
$this->twig->display("tableSample.html.twig", $detail);
}
tableSample.html.twig would be like this:
<html>
<head></head>
<body>
{{ form_open }} //will display form as a **String** and not THE **HTML** like this:
<form method="post" name="form_reg" id="form_reg"></form>
{{ form_close }}
</body>
</html>
I know I'm missing something, please point me to the right way of rendering this. Thank You!
ok, I think I got it. raw made it possible. Twig Raw Filter