Skip to content

Commit

Permalink
Add Post_Type_Page_Option and Post_Type_Page_State classes
Browse files Browse the repository at this point in the history
  • Loading branch information
gchtr committed Jun 28, 2019
1 parent e93b9df commit eee9f00
Show file tree
Hide file tree
Showing 9 changed files with 283 additions and 13 deletions.
7 changes: 7 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,12 @@
# Types

## 2.4.0 - 2019-06-28

- Added `Post_Type_Page_Option` class, which registers an option to select the page to act as the custom post type archive in the Customizer for you.
- Added `Post_Type_Page_State` class, which adds a post state label to the the pages overview in the admin to recognize pages that act as custom post type archives quicker.

Read more about this functionalities in the [`page_for_archive`](https://github.com/mindkomm/types#page_for_archive) section in the README.

## 2.3.2 - 2019-06-07

- Added edit page link to admin bar for archive pages.
Expand Down
51 changes: 46 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,9 @@
Custom Post Types and Taxonomy helper classes for WordPress projects.

- Register Custom Post Types and Taxonomies through an array notation. Labels will be set accordingly. Currently, English and German languages are supported.
- Change the query arguments for posts in the front- and backend via a list of arguments, e.g. to set a custom post order.
- Change the query arguments for posts in the front- and backend via a list of arguments, e.g. to set a custom post order wit the [`query`](#query) option.
- Change the admin columns for posts in the backend via a list of arguments.
- Set a specific page as the archive page for a custom post type with the [`page_for_archive`](#page_for_archive) option.
- Set post slugs dynamically when posts are saved.

## Table of Contents
Expand Down Expand Up @@ -172,25 +173,65 @@ If you need more possibilities for defining admin columns you could use the fant
The `page_for_archive` option allows you to set a specific page as the archive page for a custom post type:

```php
'partner' => [
'event' => [
'args' => [
'public' => true,
],
'page_for_archive' => [
'post_id' => get_option( 'page_for_partner' ),
'post_id' => get_option( 'page_for_event' ),
'is_singular_public' => false,
],
],
```

In this example, the ID for the page that’s saved in the `page_for_partner` option will act as the archive page for the `partner` post type.
In this example, the ID for the page that’s saved in the `page_for_event` option will act as the archive page for the `event` post type.

You need to **flush your permalinks** whenever you make changes to this option.

Behind the curtains, Types uses the `has_archive` option when registering a post type and set the slug of the page you passed in the `page_for_archive` option.
Behind the curtains, Types uses the `has_archive` option when registering a post type and sets the slug of the page you passed in the `page_for_archive` option.

#### is_singular_public

The `is_singular_public` option allows you to set, whether singular templates for this post type should be accessible in the frontend. Singular template requests will then be redirected to the archive page. We can’t use the `public` or `publicly_queryable` option for this, because then the archive page wouldn’t work either.

#### customizer_section

If you want Types to register an option to select the page you want to use as your archive in the Customizer, you can use the `customizer_section` argument:

```php
'event' => [
'page_for_archive' => [
'post_id' => get_option( 'page_for_event' ),
'customizer_section' => 'event',
],
],
```

With `customizer_section`, you can define in which Customizer section the option should be displayed. This needs to be an existing section. This way, you can decide yourself whether you want to have a separate Customizer section for each custom post type, or whether you want to list all of your custom post type pages in the same section.

#### show_post_state

Types will display a post state in the pages overview for the page that you selected. If you want to disable this functionality, use the `show_post_state` option.

```php
'event' => [
'page_for_archive' => [
'post_id' => get_option( 'page_for_event' ),
'show_post_state' => false,
],
],
```

#### Use page in template

To make use of that page, you will use it in your archive page where you can now use your page as the main post.

**archive-event.php**

```php
$post = get_post( get_option( 'page_for_event' ) );
```

## Update existing post types

### Change settings for a post type
Expand Down
Binary file modified languages/types-de_DE.mo
Binary file not shown.
15 changes: 12 additions & 3 deletions languages/types-de_DE.po
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@ msgid ""
msgstr ""
"Project-Id-Version: \n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2019-06-07T11:12:23+02:00\n"
"PO-Revision-Date: 2019-06-07 11:12+0200\n"
"POT-Creation-Date: 2019-06-28T09:32:42+02:00\n"
"PO-Revision-Date: 2019-06-28 09:32+0200\n"
"Last-Translator: Lukas Gächter <lukas.gaechter@mind.ch>\n"
"Language-Team: \n"
"Language: de\n"
Expand All @@ -15,10 +15,16 @@ msgstr ""
"X-Domain: mind/types\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"

#: lib/Post_Type_Page.php:154
#. translators: Plural name of the post type
#: lib/Post_Type_Page.php:153
msgid "Edit page for %s"
msgstr "Seite für %s bearbeiten"

#. translators: Post type label.
#: lib/Post_Type_Page_Option.php:107 lib/Post_Type_Page_Option.php:159
msgid "Page for %s"
msgstr "Seite für %s"

#. translators: %s: Singular taxonomy name
#. translators: %s: Singular post type name
#: lib/Taxonomy_Labels.php:87 lib/Post_Type_Labels.php:90
Expand Down Expand Up @@ -237,6 +243,9 @@ msgstr "%s übertragen."
msgid "%s draft updated."
msgstr "%s-Entwurf aktualisiert."

#~ msgid "%s page"
#~ msgstr "%s-Seite"

#, fuzzy
#~| msgid "All %s"
#~ msgid "All %"
Expand Down
11 changes: 9 additions & 2 deletions languages/types.pot
Original file line number Diff line number Diff line change
Expand Up @@ -7,15 +7,22 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"POT-Creation-Date: 2019-06-07T11:12:23+02:00\n"
"POT-Creation-Date: 2019-06-28T09:32:42+02:00\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"X-Generator: WP-CLI 2.1.0\n"
"X-Domain: mind/types\n"

#: lib/Post_Type_Page.php:154
#. translators: Plural name of the post type
#: lib/Post_Type_Page.php:153
msgid "Edit page for %s"
msgstr ""

#. translators: Post type label.
#: lib/Post_Type_Page_Option.php:107
#: lib/Post_Type_Page_Option.php:159
msgid "Page for %s"
msgstr ""

#. translators: %s: Singular taxonomy name
#. translators: %s: Singular post type name
#: lib/Taxonomy_Labels.php:87
Expand Down
22 changes: 20 additions & 2 deletions lib/Post_Type.php
Original file line number Diff line number Diff line change
Expand Up @@ -146,11 +146,29 @@ private static function register_extensions( $post_type, $args ) {
}

if ( isset( $args['page_for_archive'] ) ) {
$page_for_archive = wp_parse_args( $args['page_for_archive'], [
'post_id' => null,
'is_singular_public' => true,
'customizer_section' => '',
'show_post_state' => true,
] );

( new Post_Type_Page(
$post_type,
$args['page_for_archive']['post_id'],
$args['page_for_archive']
$page_for_archive['post_id'],
$page_for_archive
) )->init();

if ( ! empty( $page_for_archive['customizer_section'] ) ) {
( new Post_Type_Page_Option(
$post_type,
$page_for_archive['customizer_section']
) )->init();
}

if ( $page_for_archive['show_post_state'] ) {
( new Post_Type_Page_State( $post_type ) )->init();
}
}
}
}
2 changes: 1 addition & 1 deletion lib/Post_Type_Page.php
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ public function template_redirect() {
}

/**
* Make sure menu items for our pages get the correct classes assigned
* Make sure menu items for our pages get the correct classes assigned.
*
* @param array $menu_items Array of menu items.
*
Expand Down
121 changes: 121 additions & 0 deletions lib/Post_Type_Page_Option.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
<?php

namespace Types;

use WP_Customize_Manager;

/**
* Class Post_Type_Page_Option
*
* Registers an option to select the page for your Custom Post Type in the Customizer.
*/
class Post_Type_Page_Option {
/**
* Post type.
*
* @var string
*/
private $post_type;

/**
* Customizer section.
*
* @var string
*/
private $customizer_section;

/**
* Option name.
*
* @var string
*/
private $option_name;

/**
* Post_Type_Page_Option constructor.
*
* @param string $post_type The post type to register the customizer section for.
* @param string $customizer_section The name of the customizer section where the option to set
* the page should be added to. The section already needs to
* exist.
*/
public function __construct( $post_type, $customizer_section ) {
$this->post_type = $post_type;
$this->customizer_section = $customizer_section;
$this->option_name = "page_for_{$this->post_type}";
}

/**
* Inits hooks.
*/
public function init() {
if ( ! is_admin() && ! is_customize_preview() ) {
return;
}

add_action( 'customize_register', [ $this, 'register_settings' ] );

/**
* Rewrite rules need to be flushed in the next page load after the Custom Post Type was
* registered. That’s why we first need to set a transient that we check on the next admin
* page load.
*/
add_action(
"update_option_{$this->option_name}",
[ $this, 'maybe_set_flush_transient' ],
10, 2
);
add_action( 'admin_init', [ $this, 'maybe_flush_rewrite_rules' ] );
}

/**
* Adds Customizer setting and control.
*
* @param \WP_Customize_Manager $wp_customize Customizer instance.
*/
public function register_settings( WP_Customize_Manager $wp_customize ) {
$post_type_object = get_post_type_object( $this->post_type );

$wp_customize->add_setting( $this->option_name, [
'type' => 'option',
] );

$wp_customize->add_control( $this->option_name, [
'label' => sprintf(
/* translators: Post type label. */
__( 'Page for %s', 'mind/types' ),
$post_type_object->label
),
'section' => $this->customizer_section,
'type' => 'dropdown-pages',
'allow_addition' => true,
] );
}

/**
* Sets transient to flush rewrite rules when option value changes.
*
* @param mixed $old_value The old option value.
* @param mixed $value The new option value.
*/
public function maybe_set_flush_transient( $old_value, $value ) {
if ( $old_value !== $value ) {
set_transient( "flush_{$this->option_name}", true );
}
}

/**
* Flushes rewrite rules when transient is set.
*/
public function maybe_flush_rewrite_rules() {
$transient_name = "flush_{$this->option_name}";

if ( get_transient( $transient_name ) ) {
delete_transient( $transient_name );

add_action( 'shutdown', function() {
flush_rewrite_rules( false );
} );
}
}
}
67 changes: 67 additions & 0 deletions lib/Post_Type_Page_State.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
<?php

namespace Types;

/**
* Class Post_Type_Page_State
*/
class Post_Type_Page_State {
/**
* Post type.
*
* @var string
*/
private $post_type;

/**
* Option name.
*
* @var string
*/
private $option_name;

/**
* Post_Type_Page_State constructor.
*
* @param string $post_type The post type to display the post state for.
*/
public function __construct( $post_type ) {
$this->post_type = $post_type;
$this->option_name = "page_for_{$this->post_type}";
}

/**
* Inits hooks.
*/
public function init() {
if ( ! is_admin() ) {
return;
}

add_filter( 'display_post_states', [ $this, 'update_post_states' ], 10, 2 );
}

/**
* Updates post states with page for event.
*
* @param string[] $post_states An array of post display states.
* @param \WP_Post $post The current post object.
*
* @return string[] Updates post states.
*/
public function update_post_states( $post_states, $post ) {
$post_type_object = get_post_type_object( $this->post_type );

if ( 'page' === $post->post_type
&& (int) get_option( $this->option_name ) === $post->ID
) {
$post_states[ $this->option_name ] = sprintf(
/* translators: Post type label. */
__( 'Page for %s', 'mind/types' ),
$post_type_object->label
);
}

return $post_states;
}
}

0 comments on commit eee9f00

Please sign in to comment.