如何在 OctoberCMS 中处理复杂的 URL?

How to deal with complex URLs in OctoberCMS?

我是 octoberCMS 的新手!考虑到我一直在使用其他类型的 CMS 进行开发,它们通常会自动处理 urls。 因此,让我们考虑一下我们有一个网站,其中包含国家及其相关州和城市。所有这些当然都使用模型中的关系。

如果我使用 url

创建此页面

/:country-slug

我可以通过查询 country slug 轻松访问内容

/usa

如果我想访问费城,我会这样

/:country-slug/:state-slug/:city-slug

所以这行得通

/usa/pennsylvania/philadelphia

但要使它真正起作用 并且 独一无二,您需要检查模型 "City" 是否具有与之相关的确切国家和州。 否则,如果您只检查最后一个参数 :city-slug,这将创建错误或更糟的无限重复内容,其中 state/country 的每个组合都可以与 Philadelphia 一起使用,因此这个 URL 也可以工作

/italy/california/philadelphia

这是正确的做法吗?这样每一个有多个参数的URL都需要在后台手动检查? 或者我在这里遗漏了什么? 对于很长的 URL 秒,此方法似乎非常复杂,并且对于实际的动态内容不太实用。

创建具有以下定义的页面:

url = "/:country-slug/:state-slug?/:city-slug?"

[countryComponent]
country = ":country-slug"
state = ":state-slug"
city = ":city-slug"

里面 component check if external property values 是空的,filter/search 相应地建模。 Return 404 如果没有找到模型。这不切实际吗?

看似复杂其实很简单,你只需要一次检查,需要的时候重定向到合适的位置即可。

Just use this slug /:country-slug?/:state-slug?/:city-slug?

您可以看到我们将所有 3 个都设为可选。

通过这种方式,您实际上可以记录请求并知道正在搜索哪些项目以及哪些 slug 是错误的。 (需要添加您的自定义逻辑)

  1. 如果没有正确的国家/地区重定向到错误页面或帮助解释您需要提供正确的国家/地区名称
  2. 如果国家没问题就显示它的内容。
  3. 如果国家/地区没问题而州/地区不正常,则将他们重定向到国家/地区页面以避免出现大量重复内容和错误消息。
  4. 如果国家和州可以显示国家,说明内容。
  5. 城市也是如此...

现在在您的组件或模板中,您可以执行类似的操作。

use Country;
use State;
use City;

function onStart()
{
    $whatToShow = 'country';
    $country = Country::where('slug', $this->param('country-slug'))->first();
    if(!$country) {
        // if we cant find correct country then no go
        return Redirect::to('/not-found-page');
    } 
    $this['country'] = $country;
    $this['state'] = null;
    $this['city'] = null;

    $stateSlug = $this->param('state-slug');
    // check if state slug is there
    if($stateSlug) {
        $state = Country::where('slug', $stateSlug)->first();     
        if(!$state) {
            // if we do not have state then just redirect to country URL
            $countryPageLink = $this->controller->pageUrl(
                null, // <- means same page
                ['country-slug' => $country->slug]
            );
            return Redirect::to($countryPageLink);
        }
        $this['state'] = $state;
        $whatToShow = 'state';
    }

    $citySlug = $this->param('city-slug');
    // check if city slug is there
    if($citySlug) {
        $city = City::where('slug', $citySlug)->first();     
        if(!$city) {
            // if we do not have city then just redirect to country/state URL
            $statePageLink = $this->controller->pageUrl(
                null, // <- means same page
                ['country-slug' => $country->slug, 'state-slug' => $state->slug]
            );
            return Redirect::to($statePageLink);
        }
        $whatToShow = 'city';
        $this['city'] = $city;
    }

    $this['whatToShow'] = $whatToShow;
}

In markup

{% if whatToShow == 'country' %}
    show country specific data - or better country partial
    {% partial 'country' item=country %}
{% endif %}

{% if whatToShow == 'state' %}
    {% partial 'country' item=country %}
    show country specific data - or better state partial
    {% partial 'state' item=state %}
{% endif %}

{% if whatToShow == 'city' %}
    {% partial 'country' item=country %}
    {% partial 'state' item=country %}
    show country specific data - or better city partial
    {% partial 'city' item=city %}
{% endif %}

This should work for you without any problem

如有疑问请评论。