5

Iam creating static pages for a client using Yii2. I am using yii2 because the client has some other requirements to scale up the web later. I use Yii2 Basic app. The yii2 basic has default pages like about, contact etc. The url for those pages after enabling pretty url is

 www.example.com/about

etc

Now i need to create pages

"xyz.php"

under a sub directory like

"abc"

. So i need my url to be www.example.com/abc/xyz

How do i achieve this? to be informed iam a learner, I followed url rules, helpers but did not find a strong solution.

3 Answers3

2

create a controller like StaticController.php and use the yii\web\ViewAction http://www.yiiframework.com/doc-2.0/yii-web-viewaction.html

As an example:

namespace app\controllers;

use Yii;
use yii\web\Controller;
use yii\filters\AccessControl;

/**
 * StaticController is only for displaying static pages.
 */
class StaticController extends Controller
{
    public $defaultAction = 'page';

    public function behaviors()
    {
        return [
            'access' => [
                'class' => AccessControl::className(),
                'rules' => [
                    [
                        'actions' => ['page'],
                        'allow' => true,
                        'roles' => ['@'],
                    ],
                ],
            ],
        ];
    }

    public function actions()
    {
        return [
            'page'=>array(
                'class'=>'yii\web\ViewAction',
                'viewPrefix'=>null, // or set a specific directory e.g. 'static-pages' if you want to store the static pages in a subdirectory
            ),
        ];
    }
}

And add this Rule to your UrlManager (where static is your controller name)

'urlManager' => [
    'enablePrettyUrl' => true,
    'showScriptName' => false,
    'rules' => [
        '<controller:static>/<view:.*>' => '<controller>',
        ...
    ]
]

Now you can store your static pages in the directory /view/static/

e.g. index.php, test.php or even in subdirectories /sub/test2.php

The urls would be like /static (or /static/index), /static/test1, /static/sub/test2

The 1st pathname is of course the controller name, but you can also change the url rule to something else or rename the controller.

BHoft
  • 1,593
  • 9
  • 18
  • What if i have many subfolders under views? Should I create separate controllers? – Nuthan Raghunath Oct 13 '15 at 15:36
  • you don't need it. as i have written above the controller code as it is listed above searches for files in his view folder "static" because of the Controllername StaticController. You can have there multiple subfolders and sub subfolders without problems. – BHoft Oct 13 '15 at 20:53
  • Where do you put `StaticController.php`? In the controller folder where you also have `SiteController.php`? – atsngr Apr 02 '19 at 08:22
  • yes of course the location of the StaticController is the same as for normal controllers. – BHoft Apr 03 '19 at 09:11
0

config/web.php

'urlManager' => [
    'enablePrettyUrl' => true,
    'showScriptName' => false,
    'rules' => [
        'abc/<view:\S+>' => 'site/page',
    ]
]
Sergey
  • 5,121
  • 22
  • 36
  • 1
    While this answer is probably correct and useful, it is preferred if you [include some explanation along with it](http://meta.stackexchange.com/q/114762/159034) to explain how it helps to solve the problem. This becomes especially useful in the future, if there is a change (possibly unrelated) that causes it to stop working and users need to understand how it once worked. – Kevin Brown Oct 13 '15 at 13:33
  • If I have several sub folders and static pages, then I need to declare all those bunch of pages under rules.Right? – Nuthan Raghunath Oct 13 '15 at 15:38
  • @NuthanRaghunath, right. But you can search for `cms yii2` by google for lookup how to realize this mechanism other people – Sergey Oct 14 '15 at 11:28
0

I had a situation where I wanted the URL to indicate a sub page (like 'website/page/sub-page) but I didn't think it made sense to have a separate controller. (At the moment I just have one controller; SiteController.php.)

I am recreating the site structure of an existing site in a new Yii2 Basic site.

Client has a page called 'laptop-repair' in their existing site with a number of pages linked from it, e.g. 'laptop-overheating'. So the URI needed to look like 'laptop-repair/laptop-overheating'.

The solution:

In urlManager in config>web.php I add a new rule (Nb. the order of rules is important, the earlier rules are prioritised):

'urlManager' => [
            'enablePrettyUrl' => true,
            'showScriptName' => false,
            'rules' => [
                '/' => 'site/index',
                [
                    'pattern' => 'laptop-repair/<page:.*>',
                    'route' => 'site/laptop-repair',
                    'defaults' => ['page' => 'index'],
                ],

                ...

            ],
        ],

In SiteController.php I already had an action for the page which I wanted to make into a parent page:

public function actionLaptopRepair()
{
    return $this->render('laptop-repair');
}

which I replaced with:

public function actionLaptopRepair($page)
{
    return $this->render("/site/laptop-repair/$page");
}

The leading slash is necessary to override the default behaviour of the Yii application, which is to look for the view in 'views>{controllerName}'. For example with render('laptop-repair'); the view file laptop-repair.php would need to be in 'views>site' since the name of the controller is SiteController, whereas render("/site/laptop-repair/$page"); corresponds to a view file ($page) in 'views>site>laptop-repair'. This allows you to organise your views in subdirectories.

I created a new folder called 'laptop-repair' in 'views>site', moved the view for the parent page (laptop-repair.php) into the new directory and renamed it index.php. I put the new sub pages' view files in that new directory ('views>site>laptop-repair'), alongside the parent view (index.php).

Everything worked except for the URL creation in my nav widget. Where the following worked fine before, the 'laptop-repair' link broke after I implemented the above:

echo Nav::widget([
    'options' => ['class' => 'navbar-nav ml-auto'],
    'items' => [
        ['label' => 'Home', 'url' => ['/site/index']],
        [
            'label' => 'Repair Services',
            'items' => [
                ['label' => 'Desktop PC Repairs', 'url' => ['/site/pc-repair']],
                ['label' => 'Laptop Repairs', 'url' => ['site/laptop-repair']],
                ['label' => 'Mobile Phone Repairs', 'url' => ['/site/mobile-phone-repair']],
...

The fix was simply changing the relevant line to:

['label' => 'Laptop Repairs', 'url' => ['/laptop-repair']],

Creating a link from the parent page to a sub page looks like this:

<?= Html::a('Laptop overheating?', ['laptop-repair/laptop-overheating'], ['class' => '', 'title' => 'Laptop overheating']) ?>

To add a link to the parent page to the breadcrumbs of the sub page, I replaced:

$this->title = 'Laptop Over Heating?';
$this->params['breadcrumbs'][] = $this->title;

with:

$this->title = 'Laptop Over Heating?';
$this->params['breadcrumbs'][] = ['label' => 'Laptop repair', 'url' => ['/laptop-repair']];
$this->params['breadcrumbs'][] = $this->title;

in the view file of the sub page.

wkille
  • 435
  • 5
  • 10