Create 2400 virtual routes

Permalink
Hi all,

I'm struggling with the routing of 5.7. I dont know how to solve it.

What i want:
Catch virtual urls, where cityname is the virtual part: domain.com/cityname
There are around 2400 cities. The page i need to show is a pagetype or singlepage.

What i've tried / can try:
1. Calling Route::register 2400 times is not the way to go i assume. This would take a lot of time for every single call.

2. Override the page_not_found single page. Check to see if it's a proper cityname, load the pagetype, render the view, show the output and hack the response statuscode (404 -> 200).

I went for option number 2 and got stuck. What is the best way to solve this problem? Are there any other options? Is option number 2 even possible?

Gr,
Justin

 
JustinTime replied on at Permalink Reply
UPDATE:

Something like this might work:

Using a existing page (278) and render the view manually.

Route::register('/{cityname}', function ($cityname) {
    global $c;
    if ($cityname=="test") {
        $c = Page::getById(278);
        $page = $c->getPageController();
        $page->on_start();
        $page->runAction('view');
        $page->set('city', $cityname);
        $page->on_before_render();
        $view = $page->getViewObject();
        print $view->render();
        exit;
    }
    throw new \Symfony\Component\Routing\Exception\ResourceNotFoundException();
});


This is not working though. The header_required cant find the $c object and gives an error:
Call to a member function getCollectionAttributeValue() on a non-object in file /application/elements/header_required.php
<?php
$akd = $c->getCollectionAttributeValue('meta_description');
$akk = $c->getCollectionAttributeValue('meta_keywords');
?>

How to overcome this?
JohntheFish replied on at Permalink Reply
JohntheFish
Just speculating...

Can you create a route to a controller method that accepts parameters? With single pages, each /path_part/ gets mapped to a declared parameter.

Don't know if that will work in your case.
JohntheFish replied on at Permalink Reply
JohntheFish
JustinTime replied on at Permalink Reply
i can, but its basically the same approach as above.
You still have to render a fake page by loading a single page and you'll end up with the header_required error which i still havent solved.
JustinTime replied on at Permalink Reply
Setting the page in the Request object did the trick.

Route::register('/{cityname}', function ($cityname) {
    global $c;
    if ($cityname=="test") {
        $c = Page::getById(278);
        $r = Request::getInstance();
        $r->setCurrentPage($c);
        $page = $c->getPageController();
        $page->on_start();
        $page->runAction('view');
        $page->set('city', $cityname);
        $page->on_before_render();
        $view = $page->getViewObject();
        print $view->render();
        exit;
    }


Placing the script inside a controller and connecting with a db is the next step.
Glad it works now.
JohntheFish replied on at Permalink Reply
JohntheFish
When you have it working, perhaps you can write a howto. This is the sort of detail that is badly missing from the 5.7 docs.
MrKDilkington replied on at Permalink Reply
MrKDilkington
I second that, please write a How-To when you find a solution.