Jump to content
Larry Ullman's Book Forums

"showing Static Pages" Example On Page 161 Doesn't Work? (Yiibook2)


KeepLearning
 Share

Recommended Posts

I've read through the example at the top of page 161 several times now, and I just cannot understand it. So I tried out the code, but I cannot get it to work. Here's what I did:

 

I downloaded the yiibook2_cms.zip file.

I installed it as ullman.local, and verified that it works in my browser (using Xampp on Win 7).

To be clear, the composer.json file is here: E:\xampp\htdocs\ullman\composer.json.

In Sublime Text, I opened SiteController.php, added this code, and saved the file: 

[
'page' => ['class' => 'yii\web\ViewAction']
]

As a result, my actions method now looks like this:

    public function actions()    {
        return [
            'error' => [
                'class' => 'yii\web\ErrorAction',
            ],
            'captcha' => [
                'class' => 'yii\captcha\CaptchaAction',
                'fixedVerifyCode' => YII_ENV_TEST ? 'testme' : null,
            ],
            [
            'page' => ['class' => 'yii\web\ViewAction']
            ],
        ];
    }

Then I created a new "about.php" file in the following folder:

 

E:\xampp\htdocs\ullman\views\site\page\view\about.php

 

I did this by creating 2 new folders (page and view), and by copying and modifying the existing about.php file.

 

(I'm on Windows, which uses backslashes in the path.)

 

Then I pointed my browser to:

 

ullman.local/site/page/view/about

 

This gives me the following 404 error: Object not found!

 

I also got a 404 error when I pointed my browser to:

 

ullman.local/index.php/site/page/view/about

 

However, I do get the usual about page if I go here:

 

ullman.local/index.php/site/about

 

What am I doing wrong?

Link to comment
Share on other sites

In my config/web.php file, I have this:

 

'db' => require(__DIR__ . '/db.php'),
'urlManager' => [
    'enablePrettyUrl' => true,
    'showScriptName' => true,
    'rules' => [
        '<controller:\w+>/<id:\d+>' => '<controller>/view',
        '<controller:\w+>/<action:\w+>' => '<controller>/<action>',
    ]
]
If this is set to true: 
'enablePrettyUrl' => true,
then this url does not work: 
ullman.local/index.php/site/page/view/about
 
 
However, if this is set to false: 
'enablePrettyUrl' => false,

then the same url does work:

ullman.local/index.php/site/page/view/about
 
Why does this URL not work when I enable pretty URLs?
 
 
[Edited:]
 
If I have an .htaccess file in the web folder, then I get the same result as above for this URL: ullman.local/site/page/view/about

 

In other words, pretty URLs cannot be enabled. But why?

 

Thanks.

 

 

Note: The .htaccess file contains this:

 

RewriteEngine on
# 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
Link to comment
Share on other sites

Two different factors at play here. First, "showScriptName=>true" and your .htaccess dictate whether or not index.php should be in the URL. Second, "enablePrettyUrls" dictates whether or not you need to use ?r=controller/action vs. using just /controller/action. 

Link to comment
Share on other sites

Thanks, but I knew that already. :)  The problem is that with this setting:

'enablePrettyUrl' => true,

the code in the book does not work. Here is the code that is provided in the book:

'page' => ['class' => 'yii\web\ViewAction']

Is there some way to modify the code in the book to make it work even when pretty URLs are enabled?

 

 

Thanks.

Link to comment
Share on other sites

Hi,

 

You need to modify the routes in the urlManager to work with static pages.

 

here is what I have added

 

'page/<view:\w+>'=>'site/page',
 
This means I can navigate to http://localhost/yiistuff/site/aboutand the proper page shows up.  Here are some notes from my Action method that might help
 
           
 //I added this for displaying static pages...
            //now I can goto ...site/page?view=hello
            //if you want pretty urls, you can change in the urlManager like so.
            //'page/<view:\w+>'=>'site/page',
            //which means navigating ...site/page/hello
            
            //the directory where the hello.php resides is pages (this is the default).
            //you can change the directory by specifying the viewPrefix.
            'page' => [
                'class' => 'yii\web\ViewAction',
                //'viewPrefix' => 'pages2',
            ],

Hope that helps,

 

Brent

Link to comment
Share on other sites

Thanks Brent, but I could not get it to work. Here's my URL code, including your suggestion:

 

        'urlManager' => [
            'enablePrettyUrl' => true,
            'showScriptName' => false,
            'rules' => [
                '<controller:\w+>/<id:\d+>' => '<controller>/view',
                '<controller:\w+>/<action:\w+>' => '<controller>/<action>',
                'page/<view:\w+>'=>'site/page', 
            ]
        ]

Even after adding your code, I still need to disable pretty urls to access this web page:

 

ullman.local/site/page/view/about

 

I want to be able to access the above page even when pretty URLs are enabled. 

 

By the way, is "yiistuff" an actual folder, or does it represent something else?

 

Thanks.

Link to comment
Share on other sites

Hi,

 

yiistuff is just an alias that I created in Apache.  I have several (yiistuff1, yiistuff2 etc) set up that helps mimic what i would have on a server.

 

Try experimenting with the url that you are using.  You need to remove the view and probably page as well.  so that you have

 

ullman.local/site/about

 

That should work.

 

Brent

Link to comment
Share on other sites

Ah, Brent is on to something (thanks!)! I expect, or would at least like to rule out, that your about static page is conflicting with the site/about action. To confirm this, either create a different static page (not using "about") or remove the "about" action.

Link to comment
Share on other sites

Actually, I don't think anything has worked so far. Even when I thought something was working, I was actually seeing the home page, instead of the static "About" page. So I need to start over, using a new static page that is called "testpage1" instead of "About" -- as per Larry's suggestion.

 

Here is the location of my new static page:

E:\xampp\htdocs\ullman\views\site\page\view\testpage1.php

 

It contains this code:

<?php
use yii\helpers\Html;


/* @var $this yii\web\View */
$this->title = 'About';
$this->params['breadcrumbs'][] = $this->title;
?>
<div class="site-about">
    <h1><?= Html::encode($this->title) ?></h1>


    <p>
        This is the test page for page 161 of the Ullman book.
    </p>


</div>

Here is my "actions" controller in SiteController.php:

    public function actions()
    {
        return [
            'error' => [
                'class' => 'yii\web\ErrorAction',
            ],
            'captcha' => [
                'class' => 'yii\captcha\CaptchaAction',
                'fixedVerifyCode' => YII_ENV_TEST ? 'testme' : null,
            ],
            [
            'page' => ['class' => 'yii\web\ViewAction']
            ],
        ];
    }

Here is the urlManager in web.php:

 

        'urlManager' => [
            'enablePrettyUrl' => true,
            'showScriptName' => false,
            'rules' => [
                '<controller:\w+>/<id:\d+>' => '<controller>/view',
                '<controller:\w+>/<action:\w+>' => '<controller>/<action>',
            ]
        ]

Using all of the above, with pretty urls enabled, all of the following URLs give me a 404 error:

 

ullman.local/site/page/view/testpage1

ullman.local/site/page/testpage1

ullman.local/site/testpage1

ullman.local/testpage1

 

If I disable pretty urls, like this:

'enablePrettyUrl' => false,

then all of the following URLs give me the home page, which displays "Congratulations!":

 

ullman.local/site/page/view/testpage1

ullman.local/site/page/testpage1

ullman.local/site/testpage1

ullman.local/testpage1

 

What should be displayed is this text: "This is the test page for page 161 of the Ullman book.", which is what's written in testpage1.php

 

How can I fix this? I've created a default route to show all static pages, right? Testpage1.php is a static page located in the correct folder. So it should be displayed. But it is not. So how can I make this work?

 

Thanks.

Link to comment
Share on other sites

Hi,

 

Thanks Larry I got myself a little bit confused looking at the 'about' page and figuring out the route.  Now that i have looked at a different static page (not part of site), I am okay (and feel a little silly).

 

Okay first up, your actions method has the array elements error, captcha and page.  This is like having methods actionError, actionCaptcha and actionPage.  Except that instead of coding our own methods, we are pointing each one to a class to handle the particular action.  So when we call the action page it knows to use the ViewAction class to handle the action.

 

Okay now for 'yii\web\ViewAction' the default directory is pages, so you should have this directory instead.

 

E:\xampp\htdocs\ullman\views\site\pages\view\testpage1.php

 

E:\xampp\htdocs\ullman\views\site\pages\testpage1.php

 

Next we need to make sure that the routes are set up properly.  Add the following to your config file urlManager part.

'page/<view:\w+>'=>'site/page',

Okay the left hand side is what we are seeing in the URL.  The right hand side is the route.  So the proper navigation is

 

ullman.local/page/testpage1

 

will redirect to the site controller, page action and pass testpage1 to the class etc.

 

That should be working now.

 

Brent

Link to comment
Share on other sites

Thanks Brent, but it still doesn't work for me. My static page is now located here:

 

E:\xampp\htdocs\ullman\views\site\page\testpage1.php

 

My urlManager looks like this:

        'urlManager' => [
            'enablePrettyUrl' => true,
            'showScriptName' => false,
            'rules' => [
                '<controller:\w+>/<id:\d+>' => '<controller>/view',
                '<controller:\w+>/<action:\w+>' => '<controller>/<action>',
                'page/<view:\w+>'=>'site/page',    
            ]
        ]

And I've pointed my browser to this URL:

 

ullman.local/page/testpage1

 

But I'm still getting a 404 error. 

 

I also tried changing the "page" directory to "pages" to match what you wrote above, but no luck. In other words, I still cannot get this code to work, whether pretty URLs are enabled or not:

'page' => ['class' => 'yii\web\ViewAction']

Larry, have you actually tested your example to see if it works with pretty URLs enabled and disabled? Can you please let me know?

 

Thanks.

 

Link to comment
Share on other sites

hi,

 

The directory needs to be this: 

 

E:\xampp\htdocs\ullman\views\site\pages\testpage1.php

 

Notice that it is pages not page.

 

You still access through the same url as I mentioned before.  I.e. ullman.local/page/testpage1

this link to the documentation explains that the default directory in use is pages unless otherwise specified. You reference thru page because that is what we have set up in the urlManager.

 

P.S. I've been through the same learning curve with static pages as you, but once you get it you'll be wondering why it just didn't click in the first place.

Link to comment
Share on other sites

Thanks for clarifying that. Yes, I did try renaming the "page" folder to "pages", as noted in my previous post, but that did not solve the problem.

 

Actually, I have now deleted the entire project, and re-created it, but still the problem remains. I have documented every step I have taken, as follows:

 

Start in E:\xampp\htdocs and run these:

 

composer  self-update

composer global update

composer create-project --prefer-dist yiisoft/yii2-app-basic ullman

 

Next, modify config/db.php to connect to the database, which I downloaded from the YiiBook2 website.

Also, I've previously modified the following files to allow running the site locally:

httpd-vhosts.conf

hosts

 

Point my browser to

ullman.local/

to verify that I can see the home page and the about page, and yes I can.

 

Put an .htaccess file in the ullman/web folder, with the following:

RewriteEngine on
# 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

In config/web.php, insert the following code below the db line:

        'urlManager' => [
        'enablePrettyUrl' => true,
        'showScriptName' => false,
        'rules' => [
            '<controller:\w+>/<id:\d+>' => '<controller>/view',
            '<controller:\w+>/<action:\w+>' => '<controller>/<action>',
        ]
    ]

Verify that the About page can be accessed at the following URL:

http://ullman.local/site/about

 

As per the YiiBook2 instructions, create a pages folder here ("pages" is plural):

E:\xampp\htdocs\ullman\views\site\pages

 

Create a file named testpage1.php in the folder, containing the following code:

<?php

/* @var $this yii\web\View */

use yii\helpers\Html;

$this->title = 'About';
$this->params['breadcrumbs'][] = $this->title;
?>
<div class="site-about">
    <h1><?= Html::encode($this->title) ?></h1>

    <p>
        This is the test page for page 161 of the Ullman book.
    </p>

    <code><?= __FILE__ ?></code>
</div>

Insert this line in the SiteController.php Actions method:

'page' => ['class' => 'yii\web\ViewAction']

Point the browser to these two URLs:

ullman.local/site/page/view/testpage1 (As per the book)

ullman.local/page/testpage1 (As per Brent's suggestion)

 

With pretty URLs enabled, both URLs return a 404 error.

With pretty URLs disabled, both URLs return the home page, not the testpage1.php.

 

Add this to config/web.php in the urlManager section, as per Brent's suggestion:

'page/<view:\w+>'=>'site/page',

With pretty URLs enabled, both URLs return a 404 error.

With pretty URLs disabled, both URLs return the home page.

 

Thus, the following code is still not working:

'page' => ['class' => 'yii\web\ViewAction']

I think I have followed the instructions exactly, but the problem remains. Am I doing something wrong?

Link to comment
Share on other sites

Here's what I just did to test all this:

 

1. Create a brand new installation of the basic app.

2. Add "page" to the SiteController actions() method.

3. Create a views/site/pages directory.

4. Create a views/site/pages/test.php file.

5. Went to index.php?r=site/page&view=test 

 

And that worked fine. 

 

Then I enabled pretty URLs and went to index.php/site/page/view/test and got a 404 (because it doesn't know the route). Then I added this rule:

'site/page/<view:\w+>' => 'site/page'

And I go to index.php/site/page/test in my browser and it works! That rule says that "site/page/anything" should get routed to the "page" action of the "Site" controller, and the "anything" should be passed as the value for "view". 

 

Let me know if it's still not clear. 

  • Upvote 1
Link to comment
Share on other sites

Hi Again,

 

Looking at the code and the steps you've taken, I can now see where the issue is.

 

In urlManager, the first rule that matches will be actioned.  When you look at this url

 

ullman.local/page/testpage1 (As per Brent's suggestion)

 

It will actually match this rule.

 

 

'<controller:\w+>/<action:\w+>' => '<controller>/<action>',

 

but it will also match this one

 

'page/<view:\w+>'=>'site/page',

 

So which ever rule you have first, is the one that will be actioned.  This is what is happening here, and Yii is trying to find a controller called page and an action called testpage1 - which neither exist.

 

Move the 'page/<view:\w+>'=>'site/page', to the top of the list.  I.e the most restrictive rules should be listed first, followed by the general rules and then it will work.

 

Larry's solution will work being placed at the end of the list because the url suggested won't match any of the existing general rules in place.

 

I'm sorry, I should have seen this earlier.

 

Cheers,

 

Brent.

Link to comment
Share on other sites

Thanks. But following Larry's example, this works for me:

        'urlManager' => [
        'enablePrettyUrl' => true,
        'showScriptName' => false,
        'rules' => [
            '<controller:\w+>/<id:\d+>' => '<controller>/view',
            '<controller:\w+>/<action:\w+>' => '<controller>/<action>',
            'site/page/<view:\w+>'=>'site/page',
        ]
    ]

The following two URLs now return the correct page:

 

ullman.local/index.php/site/page/testpage1

  • If there is no htaccess file, then set 'showScriptName'  to true, or omit this line altogether.
  • If there is an htaccess file, then showScriptName can be either be true or false, so it's irrelevant.

ullman.local/site/page/testpage1

  • This works only if an htaccess file is present in the web folder. 
  • showScriptName can be either be true or false, so it's irrelevant.

 

The way I see it, the order doesn't matter. What made the difference is that Larry's rule starts with "site", as opposed to starting with "page".

 

Also, for both URLs, this line can be omitted entirely:

'showScriptName' => etc

Since it can be omitted, I wonder if there is any legitimate purpose for 'showScriptName'. (It's mentioned on p. 66)

 

Anyway, I'd like to suggest that this line be added to the book:

'site/page/<view:\w+>'=>'site/page',

If this section of the book were clearer, I would not have had to devote so many hours of my scarce time to understanding it over the past 10 days. Sorry to be blunt, but I hope that feedback is helpful.

 

Thanks.

Link to comment
Share on other sites

 Share

×
×
  • Create New...