The documentation clearly explains how to get access to foobar variable in a block controller when the URL is something like example.com/page/foobar/123. I want to access the variable when there is no foobar in the path, the same way I can access it in page controllers.
For example, example.com/page/123 could be accessed in the page controller like this:
public function view($foobar = null) {
if ($foobar) {
// Do something
}
}
Is there any way to achieve this in a block controller? If not directly, is there a standard way to pass data from a page controller to a block controller?
I don’t think there is a way to pass it directly without “foobar”, since this is the part that is used in the name of action_xxx() method.
In your case, I would just parse url in block view() controller and extract ID from it.
Alternatively, if you dont mind assigning dynamic variables (yeah… it’s a little sketchy from the point of good programming practices), you can leverage $c being singleton and assign variable in page type controller
$this->c->exampleVariableName = $id;
and then you can access it inside block view controller.
The problem is, that unless the CMS knows that 123 is potentially a URL variable, it throws a 404 before I can parse the URL in the view() method.
At least, that is what I assume will happen.
If I’m correct, is there a way around that?
Is there a way to make custom routes, a la /page/{foobar}? I quickly scanned the docs about routing, but I didn’t see anything about how to use routes in the CMS context.
Edit: I’d rather avoid overloading $c. I wish there was some kind of messenger class for this.
Yes, that I know how to do. But I need to pass that value to the block controller. Is using $c really the only way?
Though the more I think about it, the more constricting using page (type) controller for this feels. I think I need to dig deeper into routing to see if I can make it work for me.
No need to pass anything from page type controller, to be honest
You can just parse url by yourself in block controller (that what I would propably do).
Since blocks are meant to be “self-contained” elements of code anyway. And they parse the same url by themselves (though with mandatory “foobar” part).
You can make your own routes, but easiest way to display “typical” pages is to use page type controllers/single page controllers.
The mandatory foobar is the problem I’m trying to solve.
The problem with using page type controllers is that the block gets now tied to the page type. It’s a price I might be willing to pay, but it brings its own type of problems with it. Also, I still can’t pass the URL variable to the block controller. Unless I use the global $c.
It looks like I can define routes in bootstrap/app.php. Do you know how to register a route as an alias to an existing page and pass parts of the URL as variables?
Route::register('/page/{foobar}', /* what goes here? */);
I think I could then use Request or something in the block controller to get the variables. Maybe.
Edit:
After doing some research, I’m pretty sure using custom routes is probably not going to work in this case, for many reasons. But I did find out that I might be able to use Request Attributes to pass data between page type controller and block controller. I’m going to give that a shot.
Thank you. I have found those, but they are not telling me how to pass the processing back to Concrete once the variable has been extracted.
My bad for not stating this clearly before, but I need to load an existing regular page, not a single page with its own custom controller. I’d rather not replicate the normal page loading logic in the route.
In any case, I think for my use case the custom route approach is a dead end, because I might have sub pages that match the route pattern. Using page type controller the sub pages work as intended, and the URL variable is used only when a matching page is not found. I don’t think I can replicate that functionality with a custom route.
Yes, you need to have page type/single page controller that has $id=null argument in view() method.
And then you have to retrieve id from url (for example using request class) in block controller.
There is no “magic” variable directly available in view() block controller that you can use.