有没有办法创建看不见的页面?

时间:2010-12-25 作者:mafu

我想添加一个页面,除非直接键入URL,否则该页面不会出现在网站上的任何位置(尤其是不在标题或页面列出的任何位置)。此外,页面/帖子应该有密码保护。

我知道如何添加密码,但我找不到方法将该页面从列表中删除。

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

你好@mafutrct:

有很多方法可以做到这一点;挑选一个其实是一个挑战!我将提出几个选项,让您探索一下(顶部的选项看起来最有希望):

我假设您正在使用wp_list_pages() 为您的菜单?如果是这样,请考虑移动到v3中的新菜单。0,您可以完全控制这些菜单中显示的内容:

SO网友:hakre

By design, wordpress does not have a property per post or page that would signal the application to not use the page in queries of the standard controller WP_Query as you asked for.

However, it\'s not that this scenario is something too far away. Let\'s look what wordpress has to offer instead.

Wordpress Post Statuses

Posts can have some status, or more precisely, they have a status. That is what you might know already. I list them with their string identifier, their naming and context if any. Every post has one of these:

  • publish (Published, post)
  • future (Scheduled, post)
  • draft (Draft, post)
  • pending (Pending, post)
  • private (Private, post)
  • trash (Trash, post)
  • auto-draft (auto-draft)
  • inherit (inherit)

Next to those, you can register your own post status. The API function to do that is called register_post_status() (Wordpress Codex) which is an undocumented function. You find it documented into source: register_post_status() (Wordpress Source). To get a post\'s status, you can use the get_post_status() (Wordpress Codex) function.

It\'s not very well documented, I assume because the concept of post statuses was not introduced as a fixed feature set but on best try and then having a look. So expect this to be a bit fragile and it\'s unknown if it can be used to actually solve your issue. But I would nevertheless stick to it, because it\'s a built-in feature which is to be expected, like custom-post-types, to be integrated more and more with each release. CPT\'s for example are not introduced since 2.8 IIRC and still not complete. It just takes some time.

This post status registration function is documented as being available since 3.0.0, so it\'s quite new. It was introduced in 12719, related Ticket is #9674.

You can imagine, that the concept is not well integrated so far.

But it\'s worth to take a look at that end, because it looks like it contains all ingredients which are important for your feature request. Post statuses have properties that are used in the controllers and models decisions to fetch content - that\'s basically why you like to control. Let\'s look what\'s in before I continue with what\'s not working / buggy:

  • public TRUE/FALSE - Known to be TRUE for Published posts. So post statuses with the public-property set to TRUE are assume to behave like published posts.
  • private TRUE/FALSE - Known to be TRUE for Private posts. Comparable to the public-property.
  • protected TRUE/FALSE - Protected most certainly stands for "password protected".
  • internal TRUE/FALSE - Example for internal post statuses are: Trash; auto-draft and inherit.
  • publicly_queryable TRUE/FALSE - If not explicitly set, all public statuses are publicly queryable.
  • exclude_from_search TRUE/FALSE - Assumed to be like the property name suggests.
  • show_in_admin_all_list TRUE/FALSE - Same.
  • show_in_admin_status_list TRUE/FALSE - Same.
  • single_view_cap TRUE/FALSE - Something special, probably worth to look into for your question.
  • _builtin - Optional, internal switch. Can be used to create built-in post statuses.

Those post status properties are not designed to work with each other. The concept more or less is that everyone of those is FALSE by default and you can set some for them to TRUE. The data-structure in wordpress is a standard class with some global accessible properties. It is added to the $wp_post_statuses global variable which acts like a singleton registry in the global namespace per request, ready to be used after init. So if you would like to see, what has been defined, add a hook at the end of init for debugging purposes:

add_action( \'init\', function() {
    var_dump($GLOBALS[\'wp_post_statuses\']);
    die();
}, 99999);

With something like that you can see what\'s in for the moment. As those are standard classes with public properties, nothing is guaranteeing data consistency here. So take care as usual with the wordpress API. Some of those most probably interfere with the functionality of others but how and when is only defined by code which is likely to change. Just take a bit care and double check with the source.

Limitations so far

So as it looks good so far to make use of post statuses, let\'s take a look for the expected to be limitations this comes with.

The admin lacks of options to make own post states available in the publish box for example. that means, you need to either patch the existing display routine or create your own UI so far for it. Patching core might be more probable as it allows you to offer code for an existing feature request (Ticket #12567) and an own post edit meta box might be interactively be interfering with the concept of the publish box.

I suggest some lightweight patch to introduce a new filter that allows to change the listing of radios. The lighter your approach is, the more likely you will get this in. I smell that core developers fear a bit to introduce any changes to that part because of it\'s complexitiy. So the less complex your changes are, the better this is.

Additionally, even if my list above suggest that there is some context for post or page, you can not setup a post status for a specific post type AFAIK. So expect that your post status is available to any custom post type as well or at least the behavior needs to be researched for any of those and properly tested on your concrete site.

So to learn about the deficiencies, it\'s always good to peek what\'s reported in trac to learn about limitations upfront. I do this by searching for the function name (and I use google to search trac next to trac search):

I think this will give you an image.

Defining your own Post Status

So one option might be to define your own post status. That would enable you to re-use existing status and their functionality (namely drafting and trashing) while maintaining your own type for your hiding purposes.

I would setup one as public = TRUE; but with publicly_queryable = FALSE;. Then I don\'t know your needs regarding URL design, so using a numeric ID might be okay. This could short-circuit all the permalinks hassles this concept might have. Instead, if identified as single request with a numeric ID, you can introduce some code, that sets public_queryable to true on for the single request (single means here, the page-data is requested directly and not for a listing). Some pseudo code:

$postStatusName = \'direct_only_queryable\'; # your custom status
IF is_single_request
AND get_post_status($request_id) == $postStatusName 
THEN $GLOBALS[\'wp_post_statuses\'][$postStatusName]->public_queryable = true;

Set within the right place which would be prior to the actual fetching of the models from the database but after you are able to identify the type of request (see Wordpress 3.0 Program Flow (Toolpress PDF) with the need to trace hooks in WP_Query and related), this can work.

It would offer a quite lightweight integration for your feature while making use of core elements to integrate it. Probably some of the plugins listed by Mike are already making use of custom post statuses, so there would already be example code.

SO网友:Philip

可以使用新菜单系统执行此操作,也可以使用Exclude Pages 插件,然后向页面添加密码。

但我的意见是使用新的Custom Menu 系统仅包括您想要的页面/类别,而不包括其他内容。

结束

相关推荐