Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Unable to set Router for single Blog post #70

Open
sidekick-xx opened this issue Oct 23, 2020 · 7 comments
Open

Unable to set Router for single Blog post #70

sidekick-xx opened this issue Oct 23, 2020 · 7 comments

Comments

@sidekick-xx
Copy link

Hi Dave
Firstly, thank you very much for such a great project. I'm quite new to PHP MVC architecture and I'm stuck displaying single items for the blog system I'm practising on. I can add items to db using forms and display them as a list. Everything works perfect, so far. Except for displaying a single item. I get "Message: 'No route matched.'". My code is below and I hope you can advise me. Thanx in advance.

Blogs.php (controller):
`/**
* Display a single Blog post
*
* @return void
*/
public function showAction($blogsID) {

    $blog = $this->BlogsModel->getBlogByID($this->blogsID);

    $data = [
      'blog' => $blog
    ];
    
    View::renderTemplate("Services/Blogs/show.php", $data);
}`

Blog.php (model):
`/**
* Show single blog post
*/

public function getBlogByID($blogsID){   
    
    $this->db->query("SELECT * FROM afrioUserContent.blogs WHERE blogsID = :blogsID");
    $this->db->bind(':blogsID', $blogsID);

    $row = $this->db->single();

    return $row;
  }`

blogs.twig (view) readmore link below:
<a id="readMore" href="/blogs/{{ blog.blogsAlias }}" class="btn btn-success">ReadMore</a><?php ?>

index.php (front controller):
// Blog Links $router->add('blogs', ['controller' => 'Services\Blogs', 'action' => 'index']); $router->add('blogs/new', ['controller' => 'Services\Blogs', 'action' => 'new']); $router->add('blogs/show/index', ['controller' => 'Services\Blogs', 'action' => 'show']);

@daveh
Copy link
Owner

daveh commented Oct 23, 2020

To pass a value in using the URL, first you need to specify it in a route. For example, in the front controller:

$router->add('blogs/show/{id:\d+}', ['controller' => 'Services\Blogs', 'action' => 'show']);

The regular expression needs to match whatever the variable needs to contain, so for example if it's a numeric ID, \d+ will work. If you want it to contain letters, try \w+ or [\w-]+.

This will match URLs like blogs/show/123 for example.

Then, to get the value of the variable in the controller, you have to use the route_params property. At the moment the framework doesn't support action method arguments. So for example:

public function showAction()
{
   $id = $this->route_params['id'];

    ...

Action method arguments are coming in a future version of the framework. (no ETA at the moment)

@sidekick-xx
Copy link
Author

Hello Dave
Thanx for your speedy response
I have updated my code with the suggestions you gave. I manage to get the slug of the post in the url on clicking the Readmore button, which is what I want. I also didnt want the "show" action to be in the url so I managed to get rid of that. It looks like:
http://localhost/blogs/test-blog-4
Unfortunately it still gives Message: 'No route found!' I just can't seem to get a single page view!

@sidekick-xx
Copy link
Author

Thank you very much, Dave

@sidekick-xx sidekick-xx reopened this Oct 28, 2020
@sidekick-xx
Copy link
Author

Hi Dave
I closed this issue so I could see if I could resolve the issue myself and thus learn from it. I experimented with different examples and did make progress, I believe. However the error message has taken on a new face. When clicking the ReadMore button, the correct slug gets displayed in the URL but the wrong post is displayed. Always post with Id 1. Here is my changed code:
Blogs.php (controller)
`public function showAction() {

    $blog = BlogsModel::getBlog($blogsID = 'blogsID');
    $user = BlogsModel::getBlog($blogsUserID = 'blogsUserID');

    $data = [
        'blog' => $blog,
        'user' => $user
    ];

    View::renderTemplate("Services/Blogs/show.php", $data);
}`

Blog.php (model)
`public static function getBlog($blogsID) {

    try {
        $db = static::getDBUserContent();

        $stmt = $db->query('SELECT *, 
                            blogsID as blogsID,
                            blogsUserID as blogsUserID
                            FROM afrioUserContent.blogs
                            INNER JOIN afrioAccounts.accountsUsers
                            ON blogs.blogsUserID = accountsUsers.userID
                            ');

        $result = $stmt->fetch(PDO::FETCH_OBJ);

        return $result;
        
    } catch (PDOException $e) {
        echo $e->getMessage();
    }
}`

index.php (front controller)
$router->add('blogs/[\w-]+', ['controller' => 'Services\Blogs', 'action' => 'show']);

Thanx in advance

@daveh
Copy link
Owner

daveh commented Oct 28, 2020

First you need to specify the name of the variable when you specify the route:

$router->add('blogs/{id:[\w-]+}', ['controller' => 'Services\Blogs', 'action' => 'show']);

Then in the controller action, you can get the value of this from the URL like this:

public function showAction()
{
    $id = $this->route_params['id'];

    ...

You then need to pass this to your model method, and use it in a WHERE clause in your SQL, so the record selected is based on the value from the URL.

@sidekick-xx
Copy link
Author

Good day sir
I trust you are well.
I finally managed to sort out my issue. It took a lot of reading, trying things, watching Youtube videos and rechecking your suggestions. Then it dawned on me that I actually probably don't even grasp the concept of MVC design architecture. But I think my mindset is slowly moving in that direction. And it's quite exciting.
That being said, I have decided to go for your PHP MVC course at Udemy and give myself time to learn until it becomes as second nature to me as procedural PHP.
A great thank you to you for your expertise, time and patience.

@daveh
Copy link
Owner

daveh commented Oct 30, 2020

@sidekick-xx thank you so much for your kind words! If you have any questions when you're on the course, please don't hesitate to ask in the Q&A section of the course.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants