Style admin page in Yii - php

Im here again with a question about yii framework.
I've got a page under views/myviewname/admin.php.
I've got a page under views/myotherviewname/admin.php.
Now i want to give those pages another style. But how do i do that?
I've created a page under themes/classis/views/myviewname/admin.php and in that file i got this:
<?php /* #var $this Controller */ ?>
<?php echo $content; ?>
But i get an error. Because $content is not defined.
How do i style those pages? Would be nice if i can style all admin pages at once.

First of all, this is undeniable that $content variable will be known as undefined, since it can only be used in Layouts, not Views.
As you probably know, if you already have set a theme for your application(in main config file by 'theme'=>'myTheme'), Yii looks for that into themes/myTheme and all views will be rendered in themes/myTheme/views/x/y.php instead of views/x/y.php. Also, your layouts will be overridden by layouts located into themes/myTheme/layouts.
Now, lets assume that we want to create 2 themes:
DarkTheme
LightTheme
We should create structures like below:
+themes
+darkTheme
+views
+layouts
+main.php
+myLayout1.php
+myLayout2.php
+myController
+myView1.php
+lightTheme
+views
+layouts
+main.php
+myLayout1.php
+myLayout2.php
+myController
+myView1.php
We have a main.php which holds our base theme structure(skeleton), and 2 layouts named myLayout1.php and myLayout2.php respectively. Also we already defined a default layout into our base controller(Usually Controller.php) like below:
public $layout='//layouts/myLayout1';
Now, we have a main layout which shows everything inside myLayout1 by default. We can change layout in out action like below:
$this->layout="myLayout2";
Also we can change application theme like below:
Yii::app()->theme="lightTheme";
Note: Theme name is case-sensitive. If you attempt to activate a theme that does not exist, Yii::app()->theme will return null.
Above codes can be written into beforeAction() method or every action. Please note that, if you render myView1($this->render('myView1')) and if the theme is set to darkTheme, Yii will render themes/darkTheme/views/myController/myView1.php instead of views/myConteoller/myView1.php.
To be more clear, $content will be used in layouts. Also, this is remarkable that, $content will be replaced by everything inside a view. So if you want to modify the whole page's schema, you must modify main.php layout. In front, if you want to modify the style of a view's content, you need to modify your layout.

Related

silverstripe: use another "root" - template instead of "Page.ss"

Is it possible to render another "root" template instead of the Page.ss file for some specific pages / controllers? There are already some pages using the Page.ss template, but now there will be a new "Intranet" section on the website where the pages should have another "root" template: IntranetPage.ss.
Page.ss should stay as is and should not be touched at all.
I mainly want different "root" templates because both templates load different JS and CSS files. Also the "container" HTML is quite different.
I was able to create a custom controller which does manually what I need. Something like this:
class IntranetPageController extends PageController
{
public function index()
{
return $this->customise([
'Layout' => $this->renderWith(['Intranet/Layout/IntranetPageLayout'])
])->renderWith(['Intranet/IntranetPage']);
}
}
The code is inspired from here: https://docs.silverstripe.org/en/4/developer_guides/templates/rendering_templates/
IntranetPage.ss is used now as the "root" template. IntranetPageLayout.ss is displayed for the $Layout placeholder.
That seems to work, however I have many pages which have to be based on IntranetPage.ss. It feels strange to write for every new Controller the very same index function (with a small adjustment to load another LayoutPage).
I am sure, Silverstripe has some convention to do that automatically :)
What I need is very close to having a individual theme per page, but I am not sure if that is possible...
Instead of extending PageController, extend your IntranetPageController in new controllers. Whenever index is called, it will call your index function from your parent class, in your case IntranetPageController.

Fat Free PHP Layouts

I'm going through some of the code and projects provided here http://fatfreeframework.com/development. My goal is to create a lightweight MVC kickstarter projecting using F3. I know it's been done before, but I'm using this as a learning exercise and I hope to have something useful come out of it in the end.
The biggest stumbling block I'm coming across right now is the concept of layouts. I know the documentation mentions using templates within templates, but I'm struggling to implement it in practice. In the end, I want to have 1 or 2 layouts (default layout, maybe a custom one for modal popups, etc), and then have my views rendered wrapped inside of those layouts. I want a default layout and then the ability to override the default for the few pages that need custom ones. Here's the code I've been using:
// this is the handler for one of my routes, it's on a controller class called Index
public function index($f3, $params)
{
// this (or anything else) should get passed into the view
$f3->set('listOfItems',array("item1", "item2"));
// set the view
$f3->set('content', 'index.htm')
// render the layout
\Template::instance()->render('layout.htm');
}
Unfortunately, I keep getting a blank page. Am I going about this completely the wrong direction, or am I on the right track? Is there a way to set a default layout somewhere so it's used until it's overridden?
Well you could create a base class with a default layout. Then you extend it for each controller class. For example:
abstract class Layout {
protected $tpl='layout.htm';
function afterRoute($f3,$params) {
echo \Template::instance()->render($this->tpl);
}
}
Then:
class OneController extends Layout {
function index($f3,$params) {
$f3->set('listOfItems',...);
$f3->set('content','one/index.htm');
}
}
class AnotherController extends Layout {
protected $tpl='popup.htm';//override default layout here
function index($f3,$params) {
$f3->set('listOfItems',...);
$f3->set('content','another/index.htm');
}
}
In layout.htm:
<body>
<div id="content">
<include href="{{#content}}" if="isset(#content)"/>
</div>
</body>
Structure of the UI folder:
/ui
|-- layout.htm
|-- popup.htm
|-- one
|-- index.htm
|-- another
|-- index.htm
This is just one example of how you could organize your code. F3 is loose enough to let you organize it in a multitude of ways.
I had exactly the same problem - set everything up as required, rendered the layout, and kept getting a blank page. Also when I checked the HTML source of the rendered page it was completely empty.
If you look closely however rendering the layout is not enough, you have to also print it using the echo command. So rather than the following example which appears at first glance to be correct:
$f3->route('GET /',
function($f3) {
// Instantiates a View object
$view = new View;
// Render the page
$view->render('template/layout.php');
you actually need the last line to start with echo:
echo $view->render('template/layout.php');
For more examples see:
http://fatfreeframework.com/views-and-templates
https://www.digitalocean.com/community/tutorials/how-to-use-the-fat-free-php-framework
http://takacsmark.com/fat-free-php-framework-tutorial-4-database-models-crud/
Also for some reason (which I'm sure will become clear soon - I've only just started using the Fat Free Framework) you seem to also be able to render an .htm file which contain embedded PHP (i.e. they don't have to have the .php extension).

using layout in themes from inside module Yii PHP

In Yii application I used own theme(demirTheme) have modules(retail, corporate), and layouts(main, layout_retail, layout_corporate).
When rendering one page(ex index) I want my app to render page, related layout (retail vs corporate) and then main accordingly. How can I achieve this?
I read layout tutorials and questions no help. They only mention about changing layout path, setting default layout for module, and so on.
I tried
to put all layouts in themes layouts folder,
to put main layout in themes layouts folder and other two in modules layouts folder respectively by their module,
to put all layouts in protected/view/layouts folder,
to put all layouts in modules and one copy of main layout for each module
But can't get it work. I tried changing layout path and other settings.
Is there any way? Have you done layout rendering like this? Any suggestions welcome.
add public $layout='//layouts/layout_retail'; in the controller you want to apply the layout to (so in every controller in the retail module for example). The views should be in "protected/view/layouts"
http://www.yiiframework.com/doc/api/1.1/CController#layout-detail
I am also sure you can put the layouts in the modules map. I however use the above methode for our admin module.
http://www.yiiframework.com/doc/api/1.1/CWebModule#layout-detail
EDIT:
You retail or corporate layout should be then like the code underneath. So the retail or corporate layout would be inside the main layout. Clearly it should contain more then just this, but the content of you layouts should be within $this->beginContent('//layouts/main'); and $this->endContent();
<?php $this->beginContent('//layouts/main'); ?> //main
<div id="content">
<?php echo $content; ?> //viewOfRetail
</div>
<?php $this->endContent(); ?>
For the newcomers: in many help forums of the Internet, when someone asks about theming a module, everyone suggests a path alias to the themes folder, and I disagree with those other forums. I think this is wrong, because it implies modules to be splitted, and modules are supposed to be a black-box that can be used across projects. The advice given in such forums would only be valid if a theme is shared among several modules. If someone wants to "package" a theme inside a module, she can:
-add an init function to the controller of the module
-inside that init, use the class attribute layout and a path alias, like this, supose a module whose id is "Sample":
then you add, to SampleController.php:
public function init() {
//BELOW: it will use the layouts/main.php inside the module.
$this->layouts = "sample.views.layouts.main";
}
Yo can check about path alias here:
http://www.yiiframework.com/doc/guide/1.1/en/basics.namespace

Where can i save my block in cakephp directory structure that will contain all my menu links?

I want to create my custom theme in CakePHP. Where can I save my block in CakePHP directory structure that will contain all my menu links? And how can I fetch the file from View\Themed\MyTheme\Layouts\default.ctp?
Either use Elements (if your navbar shows on every single view) or use View Blocks (if navbar only shows on some views).
In your default.ctp file you would just do..
echo $this->element('navbar');
Which would render Views/Elements/navbar.ctp onto Views/Layouts/default.ctp (if you are using the default layout).
To access: View\Themed\MyTheme\Layouts\default.ctp, in (Cake 2.1+), you must tell cake which theme you want to use like so:
public $theme = 'MyTheme';
// or override in an action:
$this->theme = 'MyTheme';
Then:
$this->layout = 'default';
will refer to your View\Themed\MyTheme\Layouts\default.ctp.
If cake can't find the requested view file in MyTheme, it will fallback to app/View to find it.
In this way you can override views in your theme as needed.
So if you place your menu in View/Elements/menu.ctp, all of your themes will be able to access it. if you want to overwrite it for MyTheme, simply create an Elements/menu.ctp within MyTheme.
The process is slightly different with previous versions of cake if I recall.
Just place it under /App/Views/Layouts. If you want to use it everywhere, call it default.ctp, it will automatically be used. Otherwise, give it a different name, and then in the controller do:
public function some_action() {
$this->layout = 'mylayout';
}
This will display some_action using your layout instead of the default.

What is Layout and what is View in ZF? When and whose variables should I use and why?

I can't understand when to use Layout's variables and when to use View's variables to get page segments on the page. Here is the picture form their Layout package tutorial ($this means the View instance everywhere):
Why Navigation, Content and Sidebar segments are got as Layout variables?
$this->layout()->nav;
But HeadTitle, HeadScript, HeadStylesheet are got straightly from View?
$this->headTitle(); // I know that this is a placeholder view helper.
// But this segment of the page logically belongs to Layout.
// and it has to be called smth like view->layout->placeholder
And why Header and Footer are from some partial method of the View but not Layout's properties?
$this->partial('header.phtml');
I've tried to change them and both ways work fine:
echo $this->nav; // I assigned navigation segment script to the View and it works;
I tried to assign Footer segment script to the Layout and it also works:
$layout->footer = $footer;
echo $this->layout()->footer; // it also works, it's displayed on the page
Any of the ways may be applied to any variable on the page. For example in Navigation segment I have a lot of variables to display and I can output them using both ways - one variable as Layout's property, another one sa View's property.
So what is the rule to use them right way? When should I use View's variables and when Layout's ones?
I agree that this isn't very clear from the documentation, and I don't think $this->layout()->nav is explained at all. A few points that might help:
$this->layout() is actually a call to the layout view helper, which returns the current instance of Zend_Layout.
Zend_Layout registers its own placeholder helper (with the key 'Zend_Layout'), and by default creates a 'content' variable in this.
the Zend_Layout class has a magic __get() method which proxies any member variable calls over to its registered placeholder container. So calling $this->layout()->content is another way of writing $this->placeholder('Zend_Layout')->content
the Zend_Layout class also has a magic __set() method that proxies stored data to the placeholder class. So $layout->footer = 'foo' is the same as calling $this->placeholder('Zend_Layout')->footer = 'foo' in the view
With that in mind:
Why Navigation, Content and Sidebar segments are got as Layout variables?
As these are accessing data stored in Zend_Layout's placeholder. You could also use $this->placeholder('Zend_Layout')->content
But HeadTitle, HeadScript, HeadStylesheet are got straightly from View?
These are view helpers.
And why Header and Footer are from some partial method of the View but not Layout's properties?
This is the standard way of accessing content from other templates.
In general, assume that using the view object is the correct way to access the data. Use the layout object/helper only if you know the data is in the layout placeholder.
The advantage of using placeholders over partials is that you can access and modify them in several different places, including in the view itself. For example say you had a sidebar which is stored in a partial. If you were to store this in the Zend_Layout placeholder instead (for example in a controller plugin), you can then override this for certain actions in the controller:
public function someAction()
{
$this->view->layout()->sidebar = 'Some other sidebar content';
}
or in the view script itself:
<?php $this->layout()->sidebar = 'Content for this page only'; ?>

Categories