sandro87
sandro87

Hello this is definitely something stupid since it has to be possible but I can't seem to find a solution

My page city.htm

title = "city"
url = "/data/:countryslug/:cityslug"
layout = "default"
is_hidden = 0

[cities]
==
function onEnd()
{
    $this->page->title = $this->page['var']->name; //test 1
    $this->page->title = $this->page['var']; //test 2
}
==
{% set city = cities.getCity %}

twig code

my cities component

    public function onRender()
    {
        // This code will be executed before the default component
        // markup is rendered on the page or layout.
        $this->page["var"] = $this->city->name; //wont' work
        $this->page["var"] = "test" // test 2,doesn't work either
    }

    public function getCity()
    {
        //check if city exists, with the slug country
        $city = City::with("data.type", "data.datalist")
            ->where("slug", $this->param("cityslug"))
            ->whereHas('country', function ($query) {
                $query->where('slug', $this->param("countryslug"));
            })->first();

        if (!$city){
            echo "City not found";
        }
        $this->page["var"] = $city // not working
        return $this->city = $city;
    }

However $this->page["var"] seems to be inaccessible in the code section of the page. It's written in the documentation it can be accessed like this :\

The properties of a page can be accessed in the PHP code section, or Components by referencing $this->page.

Either I'm calling it at the wrong time or with the wrong variable name. What I'm trying to do is set the title of the page based on the component output and that output must come from any methods in that component not just from getCity() in this case. Also shouldn't October/PHP throw an error when variables don't exist?

mjauvin
mjauvin

From a component, you can set a twig variable (when using $this->page['var'] but it won't be accessible from the php code section unless it's an actual cms page property (like $this->page['title'], which you could actually set from within the component)

mjauvin
sandro87
sandro87

Hi, thanks! That example is working but how do I set the value of $this->foo so that is set after getCity() is ran? Is that even possible?

Also I couldn't find anywhere from the official documentation you need to access the proprierity with this long and weird syntax

$this->page->components['example']->foo;

Online I only found people accessing it with

$this->page['foo'];

I mean, shouldn't setting the title based on the content coming from a component method something very "mainstream"? :)

Last updated

mjauvin
mjauvin

Why not set the page title directly from the component?

sandro87
sandro87

Can it be done?

mjauvin
mjauvin

Yes, like this:

$this->page['title']  = "value" ;
sandro87
sandro87
    public function onRun()
    {
        $this->page["title"] = "value";
    }

in the component? It's not working, that value is not set.

mjauvin
mjauvin

Sorry, try this instead:

    public function onRun()
    {
        $this->page->title = "value";
    }
sandro87
sandro87

Finally, this seems to work! But how can it work? I thought that the twig code is rendered after the page title is set.

Now that I get the title passed to the page is it possibile to add a string on PHP code of the page or the page cycles does not allow it?

Last updated

mjauvin
mjauvin

The complete life-cycle is explained here:

https://octobercms.com/docs/cms/layouts#layout-life-cycle

You could use the Page's onEnd() method to add to the page title once the component has been executed.

sandro87
sandro87

That's what I've been doing but it seems the Page's onEnd() is executed before {% set city = cities.getCity %} so everything set in the component when that method is called (getCity()) is not passed to onEnd().

Last updated

mjauvin
mjauvin

What exactly are you trying to achieve? I think you're approaching it the wrong way.

sandro87
sandro87

It's written in the first message what I'm trying to do. I thought this was more straight forward, for example, how does the blog plugin set the title if you just drag and drop the component?

mjauvin
mjauvin

mjauvin said:

   public function onRun()
   {
       $this->page->title = "value";
   }
sandro87
sandro87

OK I finally got it and I now understand I was approaching this the wrong way. Basically I was expecting onRun() method in the component to be called when this twig part was called

{% set city = cities.getCity %}

instead it's called directly in the

[cities] 

part before everything so it's obvious that since twig is called last instead, everything set at the point won't be available to the PHP section (which is ran before twig!).

I need to process the title it so I solved it like this

title = "city"
url = "/data/:countryslug/:cityslug"
layout = "default"
is_hidden = 0

[cities]
==
function onEnd()
{
   $cities = $this->components['cities'];
   $this["city"] = $cities->getCity();
   $this->page->title = "You are in ".$this["city"]->name;
}
==
twig code

This way {{city}} is stil accessible in twig like it was before without any change. The only thing I find it weird is that I like the twing way to call methods without running anything in the PHP section. Now when I need to manipulate some output content coming from the component outside of twig I need to use this other method. Two different methods for the same thing is not ideal for keeping things readable.

Anyway, when is onRender() called in the component? it's not mentioned here https://octobercms.com/docs/cms/layouts#layout-life-cycle

Thansk @mjauvin for your help

mjauvin
mjauvin

onRender() is called in twig when you use

{% component "myComponent" %}
mjauvin
mjauvin

Looks like you're using the component as an object only... the onRender() is usefull to actually inject markup into your page... I think that's what you're missing.

mjauvin
mjauvin

in your component's onRender() method, you can set $this->page->title as well... the possibilities are endless...

sandro87
sandro87

mjauvin said:

onRender() is called in twig when you use

{% component "myComponent" %}

Isn't this useful to "print" the markup to the page from the component? I don't want that.I want to process the object in twig (in the page) so I need it as an object.

1-20 of 20