首页 > 解决方案 > 如何在 Wordpress 中动态使用页面模板文件?

问题描述

是否可以在 Wordpress 中有一个模板页面,可以动态用于不同的页面?

例如,我有一个页面模板cars.php,我想将它用于不同类型汽车的子页面,例如:豪华轿车、轿跑车、SUV、面包车。

我想要这种页面层次结构:

cars ─┬─limousine
      │
      ├─coupe
      │
      ├─suv
      │
      └─van
 

有这个链接:

example.com/cars/limousine/
example.com/cars/coupe/
example.com/cars/suv/
example.com/cars/van/

这些类型的汽车来自一个数据库,我们可以在其中添加新类型的汽车,比如蜘蛛。

我知道如何手动执行此操作,即制作页面 limousine、coupe、suv、van 和 spider 使用 Wordpress 编辑器创建它们,我会选择 car.php 作为模板。

example.com/cars/limousine/因此,在我的 cars.php 页面模板中,如果用户单击链接,我将获得例如豪华轿车类型的数据。我应该如何使用我的cars.php页面模板才能获得具有指定层次结构的页面?如果我没有明确创建每个页面(豪华轿车、双门轿车、SUV、面包车和蜘蛛),Wordpress 将如何识别链接,如何将有关特定页面的信息传递给cars.php

此致,

伊戈尔

标签: phpwordpress

解决方案


已编辑的帖子

我已经删除了我原来的回复,因为它妨碍了我。

WordPress(和许多/最现代的 CMS)的工作方式是,它们告诉 Apache、Nginx 或 IIS 等服务器执行正常工作,但如果服务器产生有效的 404,则将该结果传递到 CMS用于进一步处理的已知点(index.php)。

服务器级别

您可以挂钩的第一个地方是使用 .htaccess 文件之类的服务器级别。你可以有一个映射/cars/*到 just的规则/cars/?car_type=*。不重定向,只是映射。该地图应在服务器级别产生有效的 404,这意味着 WordPress 使用已知 URL 和可以忽略的查询字符串启动。(我有 95% 的把握这会起作用,但我现在没有可用于测试的 Apache 服务器。)您可以注册查询参数,或者您可以只使用$_GET并执行逻辑。

但我不是编辑服务器配置文件的忠实拥护者,特别是如果这需要更加动态,或者由习惯这样做的人管理。

WordPress级别

所以下一站是在 WordPress 中以某种方式处理事情。坏消息是,无论您做什么,WordPress 都会将此视为 404。但好消息是,您可以根据需要重新路由 404。

我会继续走这/cars/limo条路,但你可以根据需要进行调整。

前两个步骤是可选的,但更接近于“官方”的做事方式,我鼓励你这样做,但我稍后会解释如何跳过它们。

首先,我们需要在 WordPress 中注册一个我们感兴趣的模式。第一个参数是一个正则表达式,第二个是一个映射,最后一个说我们基本上想要胜过其他规则。添加此代码或对其进行任何更改后,您需要刷新 WordPress 永久链接。此外,如果您在本地开发并且根本没有启用重写,则需要打开它们。

add_action(
    'init',
    static function () {
        add_rewrite_rule('cars/(.+)[/]?$', 'index.php?car_type=$matches[1]', 'top');
    }
);

然而,前面的事情并没有做很多事情,所以我们还需要告诉 WordPress 我们对某些查询字符串感兴趣。这个查询字符串在前面和后面的函数之间应该是相同的。

add_filter(
    'query_vars',
    static function ($query_vars) {
        $query_vars[] = 'car_type';
        return $query_vars;
    }
);

最后一步是使用魔法template_include过滤器和get_query_var. 在每个非管理页面上都会调用此过滤器,因此请小心使用它,并确保仅在保证处于特定场景中时才更改返回。get_query_var能够提取我们在第二步中注册的查询字符串。

add_filter(
    'template_include',
    static function ($template) {
        $car_type = get_query_var('car_type');
        if ($car_type) {
            // The path must be absolute
            return __DIR__ . '/cars.php';
        }

        return $template;
    }
);

对于if逻辑,您可能希望执行其他操作,例如检查数组以查看它是否在已知类型的集合中。如果可能的话,您真的应该避免在此处进行数据库调用,因为请记住,这是在每个页面上调用的。

跳过前两个步骤

如果确实说过您可以跳过前两个步骤,尽管我不推荐它,但我想向您展示如何做到这一点。我们仍将使用template_include钩子,但现在我们将手动查看 URL 并对其进行处理。这不能保证在不同的服务器环境中存活,并且您可能会遇到一些时髦的场景,所以我说跳过它。我也不打算包含用于计算页面本身的逻辑,这也应该很容易。

add_filter(
    'template_include',
    static function ($template) {
        $url = wp_parse_url($_SERVER['REQUEST_URI'], PHP_URL_PATH);
        if( YOUR LOGIC FOR PARSING URL HERE ){
            return 'cars.php';
        }

        return $template;
    }
);

推荐阅读