Cms page Parent Slug

Hello,

I am trying to set a parent slug but it is somhow not working.

Following is my component.

public function componentDetails()
    {
        return [
            'name' => 'SingleProject Component',
            'description' => 'Get a single Project by slug'
        ];
    }

    /**
     * @link https://docs.octobercms.com/3.x/element/inspector-types.html
     */
    public function defineProperties()
    {
        return [
            'slug' => [
                'type'  => 'string',
                'title' => 'Slug',
            ],
            'parentSlug' => [
                'type' => 'string',
                'title' => 'ParentSlug'
            ]
        ];
    }

    public function loadProject()
    {

        $query= PortfolioItems::where('slug', $this->property('slug'))->first();
        return $query;
    }

    public function getParentSLug(){
        // this will return a string like "project"
        return Settings::instance()->getAttributeTranslated('portfolio_slug');

    }

    public function onRun()
    {
        $this->project = $this->loadProject();
        $this->parent = $this->getParentSLug();
    }

in the layout i am soing somthing like

url = "/:parentSlug/:slug"
layout = "default"
title = "New page"

[project]
slug = ":slug"
parentSlug = "project" => this place need to be from the component
==
{% component 'project' %}

I want to have a structure like

domain.tld/{parentSlug}/{slug}

i already tried

parentSlug = “{{ parent }}”

I am striving about this and any help would be really appreciated.

Something like this

url = "/:parentSlug/:slug"

[project]
slug = "{{ :slug }}"
parentSlug = "{{ :parentSlug }}"

@daft thanks alot.

Actually what i am trying to do is pass a parameter from model to viewBag. what we are doing now is passing parameter from viewBag to Model/Twig. i want to have something in reverse order. from model to viewBag.

in this case the parentSlug parameter is from model.

not sure that what you are trying to do is making sense to me.

if the URL must contain parentSlug and slug, then it must be in the URL and cant be injected from a component

@chris thank you. yeah i am struggling with this.

what you think can be the possible way to achieve it.

I want to make the parentSlug dynamic.

if you look into wordpress they already have this functionaltiy to define a predefined parent slug for some post types. i want to achieve same thing but sa far i am not able to do it.

what would be some examples of url you have in mind?

I have a settings in the admin panel and i am getting it like this. The admin can change it anytime.

The admins are non technical people.

public function getParentSLug(){
        // this will return a string like "project"
        return Settings::instance()->getAttributeTranslated('portfolio_slug');

    }

Now scenario 1:
The admin put the slug to be “portfolio”

the URL’s will be

https://domain.tld/portfolio/test-project-1

Scenario 2:

Now the admin decide to change this slug to projects

the URL’s will be

https://domain.tld/projects/test-project-1

So it gives the admin complete control.

i understand the i can make the urls in twig like this but then the problem is that setting the parent slug.

what i have in mind (and that’s also working)

to make the complete slug like

{{ :slug }} => /project/test-project-1

now in the method i split it into array at “/” and get the last part and then can run eloquent query for the slug.

But this method is not so good. so wondering if there can be a good approach.

What you think about this? or better if you have another good solution :slight_smile:
thanks alot.

got it.

so you are looking at it the wrong way.
You are talking about the url generated before you reach that page which will be something like this in twig

[myComponent]
==
{% set parentSlug = myComponent. getParentSLug %} {# myComponent PHP code returns the value parentSlug from your function #}
<a href="{{  'my_page' | page({ parentSlug: parentSlug , slug: project.slug} ) }} ">my link with dynamic parentSlug</a>

then your page is like @daft mentioned earlier. And your second component will be able to read the parentSlug and the slug property.

url = "/:parentSlug/:slug"

[project]
slug = "{{ :slug }}"
parentSlug = "{{ :parentSlug }}"

thanks alot. that’s what i wanted. let me implement this.

what about if somone put in the url bar soemthing different from what we have in the url?

for example:

the url generated is

https://domain.tld/project/test-project-1

and now the customer put

https://domain.tld/projecttest/test-project-1

so technically it should gives 404 right?

It won’t be giving a 404.

the page will still be called by the CMS and your component project need to handle the validity of the parentSlug and handles errors if any.

To return an error 404 from a component’s function: return $this->controller->run('404');

1 Like

@chris thanks alot. yes that’s what i wanted in the end. i was really making it compicated.

i was running the 404 in compnent viewBag mehtods. that’s also work but controller method is more preferable.

Thanks alot for the help.

1 Like