简体   繁体   English

如何在 Wordpress 中动态使用页面模板文件?

[英]How can I in Wordpress use page template file dynamically?

Is it possible to have a template page in Wordpress, that could be used for different pages dynamically?是否可以在 Wordpress 中有一个模板页面,可以动态用于不同的页面?

For example, I have a page template cars.php and I would like to use it for subpages of different types of cars eg: limousine, coupe, suv, van.例如,我有一个页面模板cars.php ,我想将它用于不同类型汽车的子页面,例如:豪华轿车、双门轿车、SUV、面包车。

I would like to have this hierarchy of pages:我想要这种页面层次结构:

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

with this links:有这个链接:

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

These types of cars come from a database where we could add cars of a new type, say spider.这些类型的汽车来自一个数据库,我们可以在其中添加新类型的汽车,比如蜘蛛。

I know how to do that manually, ie making pages limousine, coupe, suv, van and spider creating them using Wordpress editor where I would choose car.php as a template.我知道如何手动执行此操作,即使用 Wordpress 编辑器创建页面 limousine、coupe、suv、van 和 spider,我会选择 car.php 作为模板。

So in my cars.php page template I would get data of, say, limousine type if a user clicked on example.com/cars/limousine/ link.因此,在我的 cars.php 页面模板中,如果用户单击example.com/cars/limousine/链接,我将获得例如豪华轿车类型的数据。 How should I use my cars.php page template so that I could get this page with the specified hierarchy?我应该如何使用我的cars.php页面模板,以便我可以获得具有指定层次结构的页面? How would Wordpress recognise the link if I didn't explicitly created each of pages (limousine, coupe, suv, van and spider), how could that info about certain page be passed to cars.php ?如果我没有明确创建每个页面(豪华轿车、轿跑车、SUV、货车和蜘蛛),Wordpress 将如何识别链接,如何将有关特定页面的信息传递给cars.php

Best regards,此致,

Igor伊戈尔

Edited post已编辑的帖子

I've removed my original response since it was getting in the way.我已经删除了我原来的回复,因为它妨碍了我。

The way that WordPress (and many/most modern CMSs) work, is that they tell the server such as Apache, Nginx or IIS to do their normal stuff, but if the server results in an effective 404, pass that result into the CMS at a known point (index.php) for further processing. The way that WordPress (and many/most modern CMSs) work, is that they tell the server such as Apache, Nginx or IIS to do their normal stuff, but if the server results in an effective 404, pass that result into the CMS at用于进一步处理的已知点(index.php)。

Server level服务器级别

The first place that you could hook into would be at the server level using something like an .htaccess file.您可以使用的第一个位置是在服务器级别,使用 .htaccess 文件之类的文件。 You could have a rule that maps /cars/* onto just /cars/?car_type=* .你可以有一个规则,将/cars/*映射到/cars/?car_type=*上。 Not redirect, just map.不重定向,只是 map。 The map should result in an effective 404 at the server level which means WordPress kicks in with a known URL and a query string that it can just ignore. map 应该在服务器级别产生有效的 404,这意味着 WordPress 使用已知的 URL 和它可以忽略的查询字符串启动。 (I'm 95% certain this would work, but I don't have an Apache server available to test with right now.) You could register the query parameter, or you could just use $_GET and perform logic. (我有 95% 的把握这会起作用,但我现在没有可用于测试的 Apache 服务器。)您可以注册查询参数,或者您可以只使用$_GET并执行逻辑。

But I'm not a big fan of editing server config files, especially if this needs to be more dynamic, or be manageable by people that are comfortable with doing that.但我不是编辑服务器配置文件的忠实拥护者,特别是如果这需要更加动态,或者由习惯这样做的人管理。

WordPress level WordPress级

So the next stop is to handle things somehow in WordPress.所以下一站是在 WordPress 中以某种方式处理事情。 The bad news is that no matter what you do, WordPress is going to consider this a 404. The good news is, however, you can reroute the 404 as you need.坏消息是,无论您做什么,WordPress 都会将其视为 404。但好消息是,您可以根据需要重新路由 404。

I'm going to keep going with the /cars/limo path, but you can adapt as necessary.我将继续使用/cars/limo路径,但您可以根据需要进行调整。

The first two steps are optional but are closer to the "official" way of doing things and I would encourage you to do them, but I'll explain later how you can skip them.前两个步骤是可选的,但更接近于“官方”的做事方式,我鼓励你这样做,但我稍后会解释如何跳过它们。

First, we need to register a pattern with WordPress that we're interested in. The first parameter is a regex, the second is a mapping, and the last says that we basically want to trump other rules.首先,我们需要用我们感兴趣的 WordPress 注册一个模式。第一个参数是一个正则表达式,第二个是一个映射,最后一个说我们基本上想要胜过其他规则。 One you add this code, or make any changes to it, you need to flush your WordPress permalinks.添加此代码或对其进行任何更改后,您需要刷新 WordPress 永久链接。 Also, if you are developing locally and don't have rewrites enabled at all, you'll need to turn them on.此外,如果您在本地开发并且根本没有启用重写,则需要打开它们。

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

The previous thing didn't do a whole lot, however, so we also need to tell WordPress that we're interested in certain query strings.然而,前面的事情并没有做很多事情,所以我们还需要告诉 WordPress 我们对某些查询字符串感兴趣。 This query string should be the same between the previous and following functions.这个查询字符串在前面和后面的函数之间应该是相同的。

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

The last step is to use the magic template_include filter along with get_query_var .最后一步是使用神奇的template_include过滤器和get_query_var This filter is called on every non-admin page, so be careful with it and make sure you only change the return if you are guaranteed to be in your specific scenario.每个非管理页面上都会调用此过滤器,因此请小心使用它,并确保仅在保证处于特定场景中时才更改返回。 The get_query_var is able to pluck out our query string that we registered in the second step. 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;
    }
);

For the if logic, you might want to perform additional things such as checking an array to see if it is in the collection of known types.对于if逻辑,您可能需要执行其他操作,例如检查数组以查看它是否在已知类型的集合中。 You really should avoid making a database call here if at all possible, because remember, this is called on every page.如果可能的话,您真的应该避免在此处进行数据库调用,因为请记住,这是在每个页面上调用的。

Skipping the first two steps跳过前两个步骤

If did say that you could skip the first two steps, and although I don't recommend it, I want to show you how you can do it.如果确实说过您可以跳过前两个步骤,尽管我不推荐它,但我想向您展示如何做到这一点。 We're still going to use the template_include hook, but now we're just going to look at the URL manually and do things with it.我们仍将使用template_include钩子,但现在我们将手动查看 URL 并对其进行处理。 This isn't guaranteed to survive across different server environments, and you could run into some funky scenarios, so I say skip it.这不能保证在不同的服务器环境中存活,并且您可能会遇到一些时髦的场景,所以我说跳过它。 I'm also not going to include logic for figuring out the page itself, that should be pretty easy, too.我也不打算包含用于计算页面本身的逻辑,这也应该很容易。

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;
    }
);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM