-
Notifications
You must be signed in to change notification settings - Fork 30
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* New block: Chapter List * Enforce no top margin
- Loading branch information
Showing
7 changed files
with
495 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,95 @@ | ||
<?php | ||
/** | ||
* Custom walker for chapter block page list. | ||
* | ||
* Identical to `Walker_Page` except with a `walk()` that ignores orphaned | ||
* pages, which are pages with an ancestor that is not published. | ||
*/ | ||
|
||
namespace WordPressdotorg\MU_Plugins\Chapter_List; | ||
|
||
class Chapter_Walker extends \Walker_Page { | ||
|
||
/** | ||
* Display array of elements hierarchically. | ||
* | ||
* Does not assume any existing order of elements. | ||
* | ||
* $max_depth = -1 means flatly display every element. | ||
* $max_depth = 0 means display all levels. | ||
* $max_depth > 0 specifies the number of display levels. | ||
* | ||
* NOTE: This is identical to `Walker::walk()` except that it ignores orphaned | ||
* pages, which are essentially pages whose ancestor is not published. | ||
* | ||
* @param array $elements An array of elements. | ||
* @param int $max_depth The maximum hierarchical depth. | ||
* @param mixed ...$args Optional additional arguments. | ||
* @return string The hierarchical item output. | ||
*/ | ||
public function walk( $elements, $max_depth, ...$args ) { | ||
$output = ''; | ||
|
||
// invalid parameter or nothing to walk. | ||
if ( $max_depth < -1 || empty( $elements ) ) { | ||
return $output; | ||
} | ||
|
||
$parent_field = $this->db_fields['parent']; | ||
|
||
// flat display. | ||
if ( -1 === $max_depth ) { | ||
$empty_array = array(); | ||
foreach ( $elements as $e ) { | ||
$this->display_element( $e, $empty_array, 1, 0, $args, $output ); | ||
} | ||
return $output; | ||
} | ||
|
||
/* | ||
* Need to display in hierarchical order. | ||
* Separate elements into two buckets: top level and children elements. | ||
* Children_elements is two dimensional array, eg. | ||
* Children_elements[10][] contains all sub-elements whose parent is 10. | ||
*/ | ||
$top_level_elements = array(); | ||
$children_elements = array(); | ||
foreach ( $elements as $e ) { | ||
if ( empty( $e->$parent_field ) ) { | ||
$top_level_elements[] = $e; | ||
} else { | ||
$children_elements[ $e->$parent_field ][] = $e; | ||
} | ||
} | ||
|
||
/* | ||
* When none of the elements is top level. | ||
* Assume the first one must be root of the sub elements. | ||
*/ | ||
if ( empty( $top_level_elements ) ) { | ||
$first = array_slice( $elements, 0, 1 ); | ||
$root = $first[0]; | ||
|
||
$top_level_elements = array(); | ||
$children_elements = array(); | ||
foreach ( $elements as $e ) { | ||
if ( $root->$parent_field === $e->$parent_field ) { | ||
$top_level_elements[] = $e; | ||
} else { | ||
$children_elements[ $e->$parent_field ][] = $e; | ||
} | ||
} | ||
} | ||
|
||
foreach ( $top_level_elements as $e ) { | ||
$this->display_element( $e, $children_elements, $max_depth, 0, $args, $output ); | ||
} | ||
|
||
/* | ||
* Here is where it differs from the original `walk()`. The original would | ||
* automatically display orphans. | ||
*/ | ||
|
||
return $output; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,80 @@ | ||
<?php | ||
namespace WordPressdotorg\MU_Plugins\Chapter_List; | ||
|
||
defined( 'WPINC' ) || die(); | ||
|
||
require_once __DIR__ . '/class-chapter-walker.php'; | ||
|
||
add_action( 'init', __NAMESPACE__ . '\init' ); | ||
|
||
/** | ||
* Registers the block using the metadata loaded from the `block.json` file. | ||
* Behind the scenes, it registers also all assets so they can be enqueued | ||
* through the block editor in the corresponding context. | ||
* | ||
* @see https://developer.wordpress.org/reference/functions/register_block_type/ | ||
*/ | ||
function init() { | ||
register_block_type( | ||
__DIR__ . '/build', | ||
array( | ||
'render_callback' => __NAMESPACE__ . '\render', | ||
) | ||
); | ||
} | ||
|
||
/** | ||
* Render the block content. | ||
* | ||
* @param array $attributes Block attributes. | ||
* @param string $content Block default content. | ||
* @param WP_Block $block Block instance. | ||
* | ||
* @return string Returns the block markup. | ||
*/ | ||
function render( $attributes, $content, $block ) { | ||
if ( ! isset( $block->context['postId'] ) ) { | ||
return ''; | ||
} | ||
|
||
$post_id = $block->context['postId']; | ||
$post_type = get_post_type( $post_id ); | ||
|
||
$args = array( | ||
'title_li' => '', | ||
'echo' => 0, | ||
'sort_column' => 'menu_order, title', | ||
'post_type' => $post_type, | ||
|
||
// Use custom walker that excludes display of orphaned pages (an ancestor | ||
// of such a page is likely not published and thus this is not accessible). | ||
'walker' => new Chapter_Walker(), | ||
); | ||
|
||
$post_type_obj = get_post_type_object( $post_type ); | ||
|
||
if ( $post_type_obj && current_user_can( $post_type_obj->cap->read_private_posts ) ) { | ||
$args['post_status'] = array( 'publish', 'private' ); | ||
} | ||
|
||
$content = wp_list_pages( $args ); | ||
|
||
$header = '<div class="wporg-chapter-list__header">'; | ||
$header .= do_blocks( | ||
'<!-- wp:heading {"style":{"typography":{"fontStyle":"normal","fontWeight":"400"}},"fontSize":"normal","fontFamily":"inter"} --> | ||
<h2 class="wp-block-heading has-inter-font-family has-normal-font-size" style="font-style:normal;font-weight:400">' . esc_html__( 'Chapters', 'wporg' ) . '</h2> | ||
<!-- /wp:heading -->' | ||
); | ||
$header .= '<button type="button" class="wporg-chapter-list__toggle" aria-expanded="false">'; | ||
$header .= '<span class="screen-reader-text">' . esc_html__( 'Chapter list', 'wporg' ) . '</span>'; | ||
$header .= '</button>'; | ||
$header .= '</div>'; | ||
|
||
$wrapper_attributes = get_block_wrapper_attributes(); | ||
return sprintf( | ||
'<aside %1$s><nav>%2$s<ul class="wporg-chapter-list__list">%3$s</ul></nav></aside>', | ||
$wrapper_attributes, | ||
$header, | ||
$content | ||
); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
{ | ||
"$schema": "https://schemas.wp.org/trunk/block.json", | ||
"apiVersion": 2, | ||
"name": "wporg/chapter-list", | ||
"version": "0.1.0", | ||
"title": "Chapter Navigation", | ||
"category": "widgets", | ||
"icon": "smiley", | ||
"description": "", | ||
"usesContext": [ "postId" ], | ||
"attributes": { | ||
"postType": { | ||
"type": "string" | ||
} | ||
}, | ||
"supports": { | ||
"html": false, | ||
"spacing": { | ||
"margin": [ | ||
"top", | ||
"bottom" | ||
], | ||
"padding": true, | ||
"blockGap": true | ||
}, | ||
"typography": { | ||
"fontSize": true, | ||
"lineHeight": true | ||
} | ||
}, | ||
"textdomain": "wporg", | ||
"editorScript": "file:./index.js", | ||
"style": "file:./style-index.css", | ||
"viewScript": "file:./view.js" | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
/** | ||
* WordPress dependencies | ||
*/ | ||
import { registerBlockType } from '@wordpress/blocks'; | ||
import { useBlockProps } from '@wordpress/block-editor'; | ||
import ServerSideRender from '@wordpress/server-side-render'; | ||
|
||
/** | ||
* Internal dependencies | ||
*/ | ||
import metadata from './block.json'; | ||
import './style.scss'; | ||
|
||
const Edit = ( { attributes, name } ) => { | ||
const blockProps = useBlockProps(); | ||
return ( | ||
<div { ...blockProps }> | ||
<ServerSideRender block={ name } attributes={ attributes } skipBlockSupportAttributes /> | ||
</div> | ||
); | ||
}; | ||
|
||
registerBlockType( metadata.name, { | ||
edit: Edit, | ||
} ); |
Oops, something went wrong.