using Application layout inside a module

Hi all,

I was wondering how to use the application layout inside a module

I have a Search module, but I want to render the views using an application layout not a module layout.

Ive tried setting the Layout path of the module to point to the application layouts folder:


$this->setLayoutPath(getPath('application.views.layouts'));

but im having trouble when rendering partials in that layout like this:


<?php $this->renderPartial('/partials/general/_top'); ?>

or


<?php $this->renderPartial('/layouts/partials/general/_footer'); ?>

which remain in a subfolder in the application layouts directory.

Ive also tried to use (with no luck):


<?php $this->renderPartial($this->getModule()->getLayoutPath().'/partials/general/_footer'); ?>

I also thing that if it works in the module it will break normal application views using this layout

Any ideas on a good aproach to this? =0]

Well solved the problem using path alias:

When it comes to partials Yii search for them in the module view path.

renderPartial uses


CController::getViewFile()

to find the view, its documentation says:




	 * Since version 1.0.3, if the controller belongs to a module, the view file

	 * will be searched under the {@link CWebModule::getViewPath module view path}.



Setting my Module viewPath was not an option as I still needed to render my own module views (but inside application layouts)

But documentation also says:




	 * Since version 1.0.2, the view name can also refer to a path alias

	 * if it contains dot characters.



So the solution was to set my module layoutPath to point to the Application layoutPath

in the module script:


$this->setLayoutPath(getPath('application.views.layouts'));

And in the layouts use a path alias to render partials, so instead of:


<?php $this->renderPartial('/partials/general/_top'); ?>

use:


<?php $this->renderPartial('application.views.layouts.partials.general._top'); ?>

I think modules should use their own layout. Application layouts should be used for entire application.

However, I imagine you want to reuse a layout among modules.

To do that, I prefer to make pieces of applications layouts that could be reused (I make a header-layout, footer-layout, and so on).

So, in my module layout, I reuse it as below:


<?php include(Yii::app()->getLayoutPath()."/main-head.php") ?>

Better to use renderPartial, by the way

I may like that, still i disagree when you say that modules should use their own layout. imagine a site that needs a search module, the results should be displayed inside the main application layout, not a search specific layout. as lets say this layout is the same as the category list layout, there is no need to create an exact copy of it but reuse it. anyway i like the:


<?php $this->renderPartial(Yii::app()->getLayoutPath()."/lists.php") ?>

idea.

hello

im implementing a user module. default action will be login. so the default URL for this will be http://site/index.php?r=user right?

but i want the URL be like http://site/user or http://site/user/login.php


EDIT

actually login action will be on SSL. users may be redirected to https://site/user/login.php

but if im correct this will not effect what im asking?


so:

can i define a path alias for this? or do i have to use an application level view for the module just like discussed here?

thanks

Well if you want (and i think you will) that your user views are displayed inside the application layout then yes, you may be concern about this. but using the solution I gave will work.

Anyway about the url the real url when inside a module will be this way

http://site/index.php?r=user/controller/action

But changing it its not a problem you can always use the UrlManager for that, you can make your urls look the way yo want with it.

You can find examples here on how to customise Urls:

http://www.yiiframework.com/doc/guide/topics.url

The path alias is used for yii to locate the file of the view.

If you need any help let me know.

Asgaroth thank you for the reply.

EDIT ----------------

i defined following url maneger rule in the app. config file (not module level):


array(

    ......

    'components'=>array(

        ......

        'urlManager'=>array(

            'urlFormat'=>'path',

            'rules'=>array(

                'user/login'=>'index.php?r=user/login',

                 ......

            ),

        ),

    ),

);

it didnt work

i got nothing but a nice 404

i think i need an example for this.


i have thinking about views of the user module. but i have not decided yet.

for the ‘list’ action i think i have to use application view. because this will be different for every app.

for the ‘create’ and ‘update’ actions i can use module specific views because they will be same (mostly) for various apps

for ‘login’ action i cant decide because for some apps it may be separate page but for others it may be a single widget or applet integrated to some other view.

i think i need other people`s opinions before going with this

have you configured the application in the main.php to actually activate the module?


'modules'=>array('user','forum',..),



http://www.yiiframework.com/doc/guide/basics.module

urlManager configuration does not change if you use application or module specific views as what you map in there its the controllers call, so either way your urlManager configuration should look something like:




'urlManager'=>array(

            'urlFormat'=>'path',

            'rules'=>array(

                'user/login'=>'moduleName/Controller/Action',

                 ......

            ),

        ),



In your case:




'urlManager'=>array(

            'urlFormat'=>'path',

            'rules'=>array(

                'user/login'=>'user/login/form',//depending on your action name no the view name

                'user/login'=>'user/login/index',//another example

            ),

        ),



Note: you can only map a rule (‘user/login’) to (as far as i know) one route configuration.

hello,

yeah i defined the


'modules'=>array('user');

in the main config of app. its not the case.

as i said before i configured ‘login’ as the default action in the DefaultController of the module. i have only DefaultController in the module_path/controllers i do not have a separate Login controller.

the default view is


module_path/views/default/login.php

i.e. i can reach the login page as:


http://site/index.php?r=user

but i can not reach from


http://site/index.php?r=user/login

i got only 404 message of the framework.

even if i have the same login view under


module_path/views/user/login.php

then i realized (with the help of your example)

i can reach the same page from


http://site/index.php?r=user/default/login

then i tried in the url manager


 'user/login'=>'user/default/login',

but i got also 404 (not the framework version but the apache ver.) from this trial.

so i start thinking may be this can not be done at all.

but this can be cleared by someone from developer team.

Ok sorry I cant help you any further, i though




 'user/login'=>'user/default/login',



would be the solution, but if it doesnt work then im out of ideas =[

I Hope a team member can help you out.

do you have mod_rewrite enabled and the appropriate contents for rewriting the url in your .htaccess, additionally (even though i’m not so sure) i think you need to configure the urlManager component to drop the script name

In config file URL Manager should be in component array like this:-




'components'=>array(

      ---------------,

      ---------------,

      'urlManager'=>array(

			  'urlFormat'=>'path',

			  'rules'=>array(

					  'post'=>'post/list',

					  'post/<id:\w+'=>'post/read',

				         ),

			  'showScriptName'=>false,

			  'caseSensitive'=>false,

	                 ),

      ---------------,

      ---------------,

                     ),



In config file Modules should be in main array like this:-




return array(

      ---------------,

      ---------------,

             'modules'=>array('module1','module2',.....),

      ---------------,

      ---------------,

            );



For rewriting the URL following things should be done in httpd file of Apache:-

1] mod_rewrite module should be uncommented.

2] In <Directory> section AllowOverride None should be replaced with AllowOverride All.

3] Application directory must contain a .htaccess file with following code:-


Options +FollowSymLinks

IndexIgnore */*

RewriteEngine on

RewriteBase /Your Application Directory Name/


# if a directory or a file exists, use it directly

RewriteCond %{REQUEST_FILENAME} !-f

RewriteCond %{REQUEST_FILENAME} !-d


# otherwise forward it to index.php

RewriteRule . index.php

You can also take the help of following links:-

http://www.yiiframework.com/doc/guide/topics.url

http://www.yiiframework.com/forum/index.php?/topic/3459-cannot-hide-index-php/page__hl__hide__fromsearch__1

Definitely all these will help you.

It’s working for me perfectly.

Thanks Asgaroth for your 2nd post.

I was on to render a part of the footer using other files or partials. I used your tutorial and the issue resolved.

Thanks

To Render the portion of any file one should use




$this->renderPartial('application.views.layouts._footer');



Thanks