如何为与用户关联的自定义URI创建模板

时间:2014-01-31 作者:thedigitalmonk

我在一个网站上工作,我正在使用一个名为Favorite Posts 因此,登录用户可以将帖子(自定义帖子类型)添加到收藏夹中。

我创建了一个名为my-favorites 这允许登录用户查看他喜欢的帖子。

现在,我需要创建一个页面,允许其他用户或访问者查看此用户的收藏夹。

所以我需要做三件事:

获取与author相关的函数,该函数返回如下链接example.com/user/username 我可以将其附加到/收藏夹以获取链接-example.com/user/username/favorites (the_author_link()get_the_author() 链接似乎链接到网站和the_author_posts_url() 输出带有名称的a标记。是否有只获取url的功能,或者修改author以显示用户?)

让WordPress使用名为favorites.php 显示此页面。(如果结构匹配,那么如何告诉WordPress使用哪个模板?)

获取用户的用户id,以便向访问者显示他/她的收藏夹。现在,我使用[favorite-post] mytemplate文件中的短代码,可以传递一个名为

[favorite-post user_id = ""]
如果页面从/author分支出来,它会自动获取用户id吗?

我找到了这个article 但它仍然处理自定义帖子类型和query_vars 我没有使用它。如何使其适用于收藏夹页面?这里提出的大多数其他类似问题都是通过对自定义帖子类型或分类法使用slug来解决的。

1 个回复
最合适的回答,由SO网友:gmazzap 整理而成

首先,您定义了一个函数(模板标记)来显示url。您可以编写一个自定义函数,以所需的格式输出url,但是,将用户名放在公共url中可能是一个安全问题。

函数可以处理链接并接受参数$user 可以是用户id或用户对象。如果传递了non,函数将尝试使用当前的post-author(如果在循环中)。

function get_user_favorites_url( $user = NULL ) {
  if ( is_int($user) ) $user = new WP_User( $user );
  if ( ! $user instanceof WP_User ) $user = get_the_author();
  if ( $user instanceof WP_User && $user->exists() ) {
    return home_url( \'user/\' . $user->user_login . \'/favorites\' );
  }
}
现在你必须让WordPress理解这种URL。为此,必须使用重写规则。

您在OP中说过您没有使用查询变量,但您应该这样做。问题是,一旦您想要使用一个非常好的永久链接,就必须使用重写规则,通过重写规则添加的任何参数都只能通过查询var访问,而不能通过$_GET.

因此:

function user_favorites_rule() {
    add_rewrite_rule( \'user/([^/]+)/favorites\', \'index.php?favorites=$matches[1]\', \'top\' );
}
add_action( \'init\', \'user_favorites_rule\', 1 );

function user_favorites_var( $vars ) {
    $vars[] = \'favorites\';
    return $vars;
}
add_filter( \'query_vars\', \'user_favorites_var\' );
添加此代码后,进入后端,访问页面“设置->永久链接”,刷新重新布线规则。

现在您有了一个url格式,当您访问该url时,WordPress将设置一个查询变量“favorites”,用所需的用户名填充它。

然而,当我们调用该url时,WordPress不会加载“收藏夹”页面。

我建议您创建一个自定义页面模板,并为其指定“我的收藏夹”页面。

因此,创建一个新的php文件,命名为\'page-favorites.php\', 在里面只写这个:

<?php
/*
Template Name: My Favorites
*/
require( \'favorites.php\' );
没有别的了。

现在,在后端创建一个页面(如果您还没有),并将刚刚创建的模板分配给它。

之后,当使用用户收藏夹url时,我们可以使用“pre_get_posts”来查询此页面。

function user_favorites_noquery( $query ) {
  if ( is_admin() || ! $query->is_main_query() || ! $query->is_home() ) return;
  $user = $query->get(\'favorites\');
  if ( ! empty($user) ) {
    $mq = array(
      \'meta_key\' => \'_wp_page_template\', \'meta_value\' => \'page-favorites.php\'
    );
    $query->set( \'post_type\', \'page\' );
    $query->set( \'meta_query\', array($mq) );           
    $query->set( \'posts_per_page\', 1);
    $query->query[\'favorites\'] = NULL;
    $query->query_vars[\'favorites\'] = NULL;
    user_favorites_get_user( $user );
    add_filter( \'template_include\', \'user_favorites_template\', 9999 );
    // following line is to prevent WordPress redirect to the page standard url
    remove_filter(\'template_redirect\', \'redirect_canonical\');
  }
}
add_action( \'pre_get_posts\', \'user_favorites_noquery\' );

function user_favorites_get_user( $user = NULL ) {
  static $the_user = NULL;
  if ( ! empty($user)  ) $the_user = $user;
  return $the_user;
}

function user_favorites_template() {
  return get_template_directory() . \'/favorites.php\';
}
使用此代码,我们告诉WordPress使用模板调用第一页\'page-favorites.php\' 需要收藏夹url时。

功能user_favorites_get_user 是一个帮助函数,用于保存所需的用户,避免使用全局变量。

功能user_favorites_template 强制WordPress加载“收藏夹”。php作为模板。

在…内\'favorites.php\' 相关部分是输出用户收藏夹帖子的shorcode。

有两种可能:一个用户已登录并希望查看自己的收藏夹帖子,或者有人(无论是否登录)希望查看用户喜欢的帖子。

可以在如下代码中进行翻译:

//favorites.php

$user_required = user_favorites_get_user();
$user = FALSE;
if ( ! empty($user_required ) ) {
  $user = get_user_by( \'login\', $user_required );
} elseif ( is_user_logged_in() ) {
  $user = wp_get_current_user();
}
if ( $user instanceof WP_User && $user->exists() ) {
  echo do_shortcode( \'[favorite-post user_id = "\' . $user->ID . \'"]\' );
} else {
  echo \'No user selected.\';
}
现在,当用户登录时,他/她可以访问urlexample.com/my-favorites (如果“my favorites”是指定给“my favorites”页面模板的页面的slug)以查看他/她自己的帖子。

任何已登录或未登录的访问者都可以使用url,如example.com/user/username/favorites 并为特定用户查看收藏夹帖子。

结束

相关推荐

order users with drag'n'drop?

有很多插件可以让你通过拖放来订购页面和/或帖子。是否有与订单用户类似的内容?如果没有,是否可以为此创建一个插件(即是否有足够的过滤器、操作等)?