Skip to content

Instantly share code, notes, and snippets.

@luminuu
Created May 8, 2020 15:38
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save luminuu/54cb444e1dfca01c58ee8cd66a818289 to your computer and use it in GitHub Desktop.
Save luminuu/54cb444e1dfca01c58ee8cd66a818289 to your computer and use it in GitHub Desktop.
ThemeZee Magazine Blocks Multiple Category Select
/**
* Full file path: src/components/controls/category-select.js
* WordPress dependencies
*/
const { __ } = wp.i18n;
const { Component } = wp.element;
const { compose } = wp.compose;
const { withSelect } = wp.data;
const { SelectControl } = wp.components;
class CategorySelect extends Component {
/**
* Returns terms in a simplified array.
*
* @param {Array} categoryInput Array of terms from getEntityRecords.
*
* @return {Array} Array of terms in simplified array.
*/
createOptions( categoryInput ) {
const categoryOptions = categoryInput.map( cat => ( { label: cat.name, value: cat.id, disabled: false } ) );
return categoryOptions;
}
render() {
const {
categoriesList,
selectedCategoryId,
onCategoryChange,
} = this.props;
const categoryOptions = this.createOptions( categoriesList );
return (
onCategoryChange && (
<SelectControl
multiple="multiple"
label={ __( 'Category', 'themezee-magazine-blocks' ) }
value={ selectedCategoryId }
options={ categoryOptions }
onChange={ onCategoryChange }
/>
)
);
}
}
export default compose( [
withSelect( ( select ) => {
const { getEntityRecords } = select( 'core' );
const query = { per_page: -1, hide_empty: true };
return {
categoriesList: getEntityRecords( 'taxonomy', 'category', query ),
};
} ),
] )( CategorySelect );
<?php
/**
* Full file path: includes/class-themezee-magazine-blocks-cache.php
* Transient caching complex database queries for more performance.
*
* @package ThemeZee Magazine Blocks
*/
// Exit if accessed directly.
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
/**
* ThemeZee Magazine Blocks Magazine Grid Class
*/
class ThemeZee_Magazine_Blocks_Cache {
/**
* Setup the class
*
* @return void
*/
static function setup() {
// Flush Cache if needed.
add_action( 'save_post', array( __CLASS__, 'flush_cached_post_ids' ) );
add_action( 'deleted_post', array( __CLASS__, 'flush_cached_post_ids' ) );
add_action( 'customize_save_after', array( __CLASS__, 'flush_cached_post_ids' ) );
add_action( 'switch_theme', array( __CLASS__, 'flush_cached_post_ids' ) );
}
/**
* Delete Cached Post IDs
*
* @return void
*/
static function flush_cached_post_ids() {
delete_transient( 'themezee_magazine_blocks_cached_post_ids' );
}
/**
* Query Posts from cache or database.
*
* @param array $attributes The block attributes.
*
* @return array Returns the post query.
*/
static function query_posts( $attributes ) {
// Get post ids from cache or database.
$post_ids = self::get_post_ids( $attributes );
// Set query arguments.
$query_arguments = array(
'post__in' => $post_ids,
'posts_per_page' => absint( $attributes['numberOfPosts'] ),
'order' => esc_attr( $attributes['order'] ),
'orderby' => esc_attr( $attributes['orderBy'] ),
'ignore_sticky_posts' => true,
'no_found_rows' => true,
);
// Fetch posts from database.
$posts_query = new WP_Query( $query_arguments );
return $posts_query;
}
/**
* Get Post IDs.
*
* @param array $attributes The block attributes.
*
* @return array Returns the post ids.
*/
static function get_post_ids( $attributes ) {
// Generate Cache ID.
$cache_id = self::get_cache_id( $attributes );
// Get cached post ids.
$cached_post_ids = get_transient( 'themezee_magazine_blocks_cached_post_ids' );
if ( ! isset( $cached_post_ids[ $cache_id ] ) || is_customize_preview() ) {
// Get query arguments.
$query_arguments = self::get_query_arguments( $attributes );
// Get Posts from Database.
$query = new WP_Query( $query_arguments );
// Create an array of all post ids.
$cached_post_ids[ $cache_id ] = $query->posts;
// Set Transient.
set_transient( 'themezee_magazine_blocks_cached_post_ids', $cached_post_ids );
}
return apply_filters( 'themezee_magazine_blocks_cached_post_ids', $cached_post_ids[ $cache_id ], $cache_id );
}
/**
* Get Query Arguments.
*
* @param array $attributes The block attributes.
*
* @return array Returns query arguments.
*/
static function get_query_arguments( $attributes ) {
$query_arguments = array(
'fields' => 'ids',
'posts_per_page' => absint( $attributes['numberOfPosts'] ),
'post_status' => 'publish',
'order' => esc_attr( $attributes['order'] ),
'orderby' => esc_attr( $attributes['orderBy'] ),
'suppress_filters' => false,
'ignore_sticky_posts' => true,
'no_found_rows' => true,
);
if ( isset( $attributes['categories'] ) ) {
$query_arguments['cat'] = esc_attr( $attributes['categories'] );
}
if ( isset( $attributes['tags'] ) ) {
$query_arguments['tag'] = esc_attr( $attributes['tags'] );
}
if ( isset( $attributes['author'] ) ) {
$query_arguments['author'] = intval( $attributes['author'] );
}
if ( isset( $attributes['offset'] ) && $attributes['offset'] > 0 ) {
$query_arguments['offset'] = absint( $attributes['offset'] );
}
return $query_arguments;
}
/**
* Get Cache ID
*
* @param array $attributes The block attributes.
*
* @return string Returns cache id.
*/
static function get_cache_id( $attributes ) {
// Add query arguments to cache id string.
$cache_id = (string) intval( $attributes['numberOfPosts'] ) . esc_attr( $attributes['order'] ) . esc_attr( $attributes['orderBy'] );
if ( isset( $attributes['categories'] ) ) {
$cache_id .= (string) esc_attr( $attributes['categories'] );
}
if ( isset( $attributes['tags'] ) ) {
$cache_id .= esc_attr( $attributes['tags'] );
}
if ( isset( $attributes['author'] ) ) {
$cache_id .= (string) intval( $attributes['author'] );
}
if ( isset( $attributes['offset'] ) && $attributes['offset'] > 0 ) {
$cache_id .= (string) intval( $attributes['offset'] );
}
return sanitize_key( $cache_id );
}
}
// Run Class.
ThemeZee_Magazine_Blocks_Cache::setup();
<?php
/**
* Full file path: includes/blocks/class-themezee-magazine-blocks-column.php
* Server-side rendering of the Magazine Column Block
*
* @package ThemeZee Magazine Blocks
*/
// Exit if accessed directly.
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
/**
* ThemeZee Magazine Blocks Magazine Column Class
*/
class ThemeZee_Magazine_Blocks_Column {
/**
* Setup the class
*
* @return void
*/
static function setup() {
// Register Block.
add_action( 'init', array( __CLASS__, 'register_block' ) );
}
/**
* Register block on server.
*
* @return void
*/
static function register_block() {
register_block_type(
'themezee-magazine-blocks/column',
array(
'attributes' => array(
'className' => array(
'type' => 'string',
),
'categories' => array(
'type' => 'array',
),
'tags' => array(
'type' => 'string',
),
'author' => array(
'type' => 'string',
),
'numberOfPosts' => array(
'type' => 'number',
'default' => 3,
),
'offset' => array(
'type' => 'number',
'default' => 0,
),
'order' => array(
'type' => 'string',
'default' => 'desc',
),
'orderBy' => array(
'type' => 'string',
'default' => 'date',
),
'imageSize' => array(
'type' => 'string',
'default' => 'full',
),
'thumbnailSize' => array(
'type' => 'string',
'default' => 'full',
),
'metaPosition' => array(
'type' => 'string',
'default' => 'below-title',
),
'showDate' => array(
'type' => 'boolean',
'default' => true,
),
'showAuthor' => array(
'type' => 'boolean',
'default' => true,
),
'showCategories' => array(
'type' => 'boolean',
'default' => false,
),
'showComments' => array(
'type' => 'boolean',
'default' => false,
),
'excerptLength' => array(
'type' => 'number',
'default' => 25,
),
'moreText' => array(
'type' => 'string',
'default' => esc_html__( 'Continue Reading', 'themezee-magazine-blocks' ),
),
),
'render_callback' => array( __CLASS__, 'render_block' ),
'style' => 'themezee-magazine-blocks',
'editor_script' => 'themezee-magazine-blocks',
'editor_style' => 'themezee-magazine-blocks-editor',
)
);
}
/**
* Render block.
*
* @param array $attributes The block attributes.
*
* @return string Returns the block content.
*/
static function render_block( $attributes ) {
// Fetch posts from cache or database.
$posts_query = ThemeZee_Magazine_Blocks_Cache::query_posts( $attributes );
// Set up markup variables.
$highlight_post = '';
$list_posts = '';
// Check if there are posts.
if ( $posts_query->have_posts() ) :
// Get Posts Markup.
while ( $posts_query->have_posts() ) :
$posts_query->the_post();
// Display first post differently.
if ( 0 === $posts_query->current_post ) :
$highlight_post .= ThemeZee_Magazine_Blocks_Template::get_grid_post( $attributes, $attributes['imageSize'] );
else :
$list_posts .= ThemeZee_Magazine_Blocks_Template::get_list_post( $attributes, $attributes['thumbnailSize'], false );
endif;
endwhile;
endif;
// Reset Postdata.
wp_reset_postdata();
// Wrap Highlight Posts.
$highlight_post = sprintf( '<div class="tz-magazine-highlight-post">%s</div>', $highlight_post );
// Wrap Thumbnail Posts.
$list_posts = sprintf( '<div class="tz-magazine-thumbnail-list">%s</div>', $list_posts );
// Set Posts Markup.
$posts_markup = $highlight_post . $list_posts;
// Define Block Content.
$block_content = sprintf( '<div class="tz-magazine-column">%s</div>', $posts_markup );
// Get Block Classes.
$block_classes = self::get_block_classes( $attributes );
// Wrap Block Content.
$block = sprintf(
'<div class="%1$s">%2$s</div>',
esc_attr( $block_classes ),
$block_content
);
return $block;
}
/**
* Get Block Classes.
*
* @param array $attributes The block attributes.
*
* @return string Returns the block classes.
*/
static function get_block_classes( $attributes ) {
$classes = 'wp-block-themezee-magazine-blocks-column';
$classes .= ' tz-magazine-block';
if ( isset( $attributes['className'] ) ) {
$classes .= ' ' . $attributes['className'];
}
return $classes;
}
}
// Run Class.
ThemeZee_Magazine_Blocks_Column::setup();
<?php
/**
* Full file path: includes/blocks/class-themezee-magazine-blocks-grid.php
* Server-side rendering of the Magazine Grid Block
*
* @package ThemeZee Magazine Blocks
*/
// Exit if accessed directly.
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
/**
* ThemeZee Magazine Blocks Magazine Grid Class
*/
class ThemeZee_Magazine_Blocks_Grid {
/**
* Setup the class
*
* @return void
*/
static function setup() {
// Register Block.
add_action( 'init', array( __CLASS__, 'register_block' ) );
}
/**
* Register block on server.
*
* @return void
*/
static function register_block() {
register_block_type(
'themezee-magazine-blocks/grid',
array(
'attributes' => array(
'className' => array(
'type' => 'string',
),
'categories' => array(
'type' => 'array',
),
'tags' => array(
'type' => 'string',
),
'author' => array(
'type' => 'string',
),
'numberOfPosts' => array(
'type' => 'number',
'default' => 6,
),
'offset' => array(
'type' => 'number',
'default' => 0,
),
'order' => array(
'type' => 'string',
'default' => 'desc',
),
'orderBy' => array(
'type' => 'string',
'default' => 'date',
),
'columns' => array(
'type' => 'number',
'default' => 3,
),
'imageSize' => array(
'type' => 'string',
'default' => 'full',
),
'metaPosition' => array(
'type' => 'string',
'default' => 'below-title',
),
'showDate' => array(
'type' => 'boolean',
'default' => true,
),
'showAuthor' => array(
'type' => 'boolean',
'default' => true,
),
'showCategories' => array(
'type' => 'boolean',
'default' => false,
),
'showComments' => array(
'type' => 'boolean',
'default' => false,
),
'excerptLength' => array(
'type' => 'number',
'default' => 25,
),
'moreText' => array(
'type' => 'string',
'default' => esc_html__( 'Continue Reading', 'themezee-magazine-blocks' ),
),
),
'render_callback' => array( __CLASS__, 'render_block' ),
'style' => 'themezee-magazine-blocks',
'editor_script' => 'themezee-magazine-blocks',
'editor_style' => 'themezee-magazine-blocks-editor',
)
);
}
/**
* Render block.
*
* @param array $attributes The block attributes.
*
* @return string Returns the block content.
*/
static function render_block( $attributes ) {
// Fetch posts from cache or database.
$posts_query = ThemeZee_Magazine_Blocks_Cache::query_posts( $attributes );
// Set up markup variable.
$posts_markup = '';
// Check if there are posts.
if ( $posts_query->have_posts() ) :
// Get Posts Markup.
while ( $posts_query->have_posts() ) :
$posts_query->the_post();
$posts_markup .= ThemeZee_Magazine_Blocks_Template::get_grid_post( $attributes, $attributes['imageSize'] );
endwhile;
endif;
// Reset Postdata.
wp_reset_postdata();
// Set Columns class.
$columns_class = sanitize_key( 'tz-magazine-grid-columns-' . $attributes['columns'] );
// Define Block Content.
$block_content = sprintf( '<div class="tz-magazine-grid-columns %1$s">%2$s</div>', $columns_class, $posts_markup );
// Get Block Classes.
$block_classes = self::get_block_classes( $attributes );
// Wrap Block Content.
$block = sprintf(
'<div class="%1$s">%2$s</div>',
esc_attr( $block_classes ),
$block_content
);
return $block;
}
/**
* Get Block Classes.
*
* @param array $attributes The block attributes.
*
* @return string Returns the block classes.
*/
static function get_block_classes( $attributes ) {
$classes = 'wp-block-themezee-magazine-blocks-grid';
$classes .= ' tz-magazine-block';
if ( isset( $attributes['className'] ) ) {
$classes .= ' ' . $attributes['className'];
}
return $classes;
}
}
// Run Class.
ThemeZee_Magazine_Blocks_Grid::setup();
<?php
/**
* Full file path: includes/blocks/class-themezee-magazine-blocks-horizontal.php
* Server-side rendering of the Magazine Horizontal Block
*
* @package ThemeZee Magazine Blocks
*/
// Exit if accessed directly.
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
/**
* ThemeZee Magazine Blocks Magazine Horizontal Class
*/
class ThemeZee_Magazine_Blocks_Horizontal {
/**
* Setup the class
*
* @return void
*/
static function setup() {
// Register Block.
add_action( 'init', array( __CLASS__, 'register_block' ) );
}
/**
* Register block on server.
*
* @return void
*/
static function register_block() {
register_block_type(
'themezee-magazine-blocks/horizontal',
array(
'attributes' => array(
'className' => array(
'type' => 'string',
),
'categories' => array(
'type' => 'array',
),
'tags' => array(
'type' => 'string',
),
'author' => array(
'type' => 'string',
),
'numberOfPosts' => array(
'type' => 'number',
'default' => 4,
),
'offset' => array(
'type' => 'number',
'default' => 0,
),
'order' => array(
'type' => 'string',
'default' => 'desc',
),
'orderBy' => array(
'type' => 'string',
'default' => 'date',
),
'columns' => array(
'type' => 'number',
'default' => 3,
),
'imageSize' => array(
'type' => 'string',
'default' => 'full',
),
'thumbnailSize' => array(
'type' => 'string',
'default' => 'full',
),
'metaPosition' => array(
'type' => 'string',
'default' => 'below-title',
),
'showDate' => array(
'type' => 'boolean',
'default' => true,
),
'showAuthor' => array(
'type' => 'boolean',
'default' => true,
),
'showCategories' => array(
'type' => 'boolean',
'default' => false,
),
'showComments' => array(
'type' => 'boolean',
'default' => false,
),
'excerptLength' => array(
'type' => 'number',
'default' => 25,
),
'moreText' => array(
'type' => 'string',
'default' => esc_html__( 'Continue Reading', 'themezee-magazine-blocks' ),
),
),
'render_callback' => array( __CLASS__, 'render_block' ),
'style' => 'themezee-magazine-blocks',
'editor_script' => 'themezee-magazine-blocks',
'editor_style' => 'themezee-magazine-blocks-editor',
)
);
}
/**
* Render block.
*
* @param array $attributes The block attributes.
*
* @return string Returns the block content.
*/
static function render_block( $attributes ) {
// Fetch posts from cache or database.
$posts_query = ThemeZee_Magazine_Blocks_Cache::query_posts( $attributes );
// Set up markup variables.
$highlight_post = '';
$grid_posts = '';
// Check if there are posts.
if ( $posts_query->have_posts() ) :
// Get Posts Markup.
while ( $posts_query->have_posts() ) :
$posts_query->the_post();
// Display first post differently.
if ( 0 === $posts_query->current_post ) :
$highlight_post .= ThemeZee_Magazine_Blocks_Template::get_list_post( $attributes, $attributes['imageSize'] );
else :
$grid_posts .= ThemeZee_Magazine_Blocks_Template::get_grid_post( $attributes, $attributes['thumbnailSize'], false );
endif;
endwhile;
endif;
// Reset Postdata.
wp_reset_postdata();
// Wrap Highlight Posts.
$highlight_post = sprintf( '<div class="tz-magazine-highlight-post">%s</div>', $highlight_post );
// Set Columns class.
$columns_class = sanitize_key( 'tz-magazine-grid-columns-' . $attributes['columns'] );
// Wrap Grid Posts.
$grid_posts = sprintf( '<div class="tz-magazine-grid-columns %1$s">%2$s</div>', $columns_class, $grid_posts );
// Set Posts Markup.
$posts_markup = $highlight_post . $grid_posts;
// Define Block Content.
$block_content = sprintf( '<div class="tz-magazine-horizontal">%s</div>', $posts_markup );
// Get Block Classes.
$block_classes = self::get_block_classes( $attributes );
// Wrap Block Content.
$block = sprintf(
'<div class="%1$s">%2$s</div>',
esc_attr( $block_classes ),
$block_content
);
return $block;
}
/**
* Get Block Classes.
*
* @param array $attributes The block attributes.
*
* @return string Returns the block classes.
*/
static function get_block_classes( $attributes ) {
$classes = 'wp-block-themezee-magazine-blocks-horizontal';
$classes .= ' tz-magazine-block';
if ( isset( $attributes['className'] ) ) {
$classes .= ' ' . $attributes['className'];
}
return $classes;
}
}
// Run Class.
ThemeZee_Magazine_Blocks_Horizontal::setup();
<?php
/**
* Full file path: includes/blocks/class-themezee-magazine-blocks-list.php
* Server-side rendering of the Magazine List Block
*
* @package ThemeZee Magazine Blocks
*/
// Exit if accessed directly.
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
/**
* ThemeZee Magazine Blocks Magazine List Class
*/
class ThemeZee_Magazine_Blocks_List {
/**
* Setup the class
*
* @return void
*/
static function setup() {
// Register Block.
add_action( 'init', array( __CLASS__, 'register_block' ) );
}
/**
* Register block on server.
*
* @return void
*/
static function register_block() {
register_block_type(
'themezee-magazine-blocks/list',
array(
'attributes' => array(
'className' => array(
'type' => 'string',
),
'categories' => array(
'type' => 'array',
),
'tags' => array(
'type' => 'string',
),
'author' => array(
'type' => 'string',
),
'numberOfPosts' => array(
'type' => 'number',
'default' => 3,
),
'offset' => array(
'type' => 'number',
'default' => 0,
),
'order' => array(
'type' => 'string',
'default' => 'desc',
),
'orderBy' => array(
'type' => 'string',
'default' => 'date',
),
'layout' => array(
'type' => 'string',
'default' => '50-50',
),
'imageSize' => array(
'type' => 'string',
'default' => 'full',
),
'metaPosition' => array(
'type' => 'string',
'default' => 'below-title',
),
'showDate' => array(
'type' => 'boolean',
'default' => true,
),
'showAuthor' => array(
'type' => 'boolean',
'default' => true,
),
'showCategories' => array(
'type' => 'boolean',
'default' => false,
),
'showComments' => array(
'type' => 'boolean',
'default' => false,
),
'excerptLength' => array(
'type' => 'number',
'default' => 25,
),
'moreText' => array(
'type' => 'string',
'default' => esc_html__( 'Continue Reading', 'themezee-magazine-blocks' ),
),
),
'render_callback' => array( __CLASS__, 'render_block' ),
'style' => 'themezee-magazine-blocks',
'editor_script' => 'themezee-magazine-blocks',
'editor_style' => 'themezee-magazine-blocks-editor',
)
);
}
/**
* Render block.
*
* @param array $attributes The block attributes.
*
* @return string Returns the block content.
*/
static function render_block( $attributes ) {
// Fetch posts from cache or database.
$posts_query = ThemeZee_Magazine_Blocks_Cache::query_posts( $attributes );
// Set up markup variable.
$posts_markup = '';
// Check if there are posts.
if ( $posts_query->have_posts() ) :
// Get Posts Markup.
while ( $posts_query->have_posts() ) :
$posts_query->the_post();
$posts_markup .= ThemeZee_Magazine_Blocks_Template::get_list_post( $attributes, $attributes['imageSize'] );
endwhile;
endif;
// Reset Postdata.
wp_reset_postdata();
// Set List class.
$list_class = sanitize_key( 'tz-magazine-list-' . $attributes['layout'] );
// Define Block Content.
$block_content = sprintf( '<div class="tz-magazine-list %1$s">%2$s</div>', $list_class, $posts_markup );
// Get Block Classes.
$block_classes = self::get_block_classes( $attributes );
// Wrap Block Content.
$block = sprintf(
'<div class="%1$s">%2$s</div>',
esc_attr( $block_classes ),
$block_content
);
return $block;
}
/**
* Get Block Classes.
*
* @param array $attributes The block attributes.
*
* @return string Returns the block classes.
*/
static function get_block_classes( $attributes ) {
$classes = 'wp-block-themezee-magazine-blocks-list';
$classes .= ' tz-magazine-block';
if ( isset( $attributes['className'] ) ) {
$classes .= ' ' . $attributes['className'];
}
return $classes;
}
}
// Run Class.
ThemeZee_Magazine_Blocks_List::setup();
<?php
/**
* Full file path: includes/class-themezee-magazine-blocks-template.php
* Display a single post.
*
* @package ThemeZee Magazine Blocks
*/
// Exit if accessed directly.
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
/**
* ThemeZee Magazine Blocks Magazine Grid Class
*/
class ThemeZee_Magazine_Blocks_Template {
/**
* Get Grid Post.
*
* @param array $attributes The block attributes.
*
* @return string Returns the post content.
*/
static function get_grid_post( $attributes, $image_size, $show_content = true ) {
$post_content = '';
// Add Featured Image.
$post_content .= self::get_post_image( $image_size );
// Add Post Header.
$post_content .= self::get_post_header( $attributes );
// Show Excerpt?
if ( true === $show_content && $attributes['excerptLength'] > 0 ) {
$post_content .= self::get_post_content( $attributes );
}
// Wrap Post Content.
$post_wrap = self::get_post_wrap( $post_content );
return $post_wrap;
}
/**
* Get List Post.
*
* @param array $attributes The block attributes.
*
* @return string Returns the post content.
*/
static function get_list_post( $attributes, $image_size, $show_content = true ) {
// Get Featured Image.
$post_image = self::get_post_image( $image_size );
// Wrap post image.
$post_image = sprintf( '<div class="tz-post-image">%s</div>', $post_image );
// Get Post Header.
$post_content = self::get_post_header( $attributes );
// Show Excerpt?
if ( true === $show_content && $attributes['excerptLength'] > 0 ) {
$post_content .= self::get_post_content( $attributes );
}
// Wrap post content.
$post_content = sprintf( '<div class="tz-post-content">%s</div>', $post_content );
// Wrap Post.
$post = self::get_post_wrap( $post_image . $post_content );
return $post;
}
/**
* Get Post Wrap.
*
* @param array $post_content The post.
*
* @return string Returns the post wrap.
*/
static function get_post_wrap( $post_content ) {
// Get Post classes as string.
$post_classes = join( ' ', get_post_class( 'tz-magazine-post' ) );
// Prefix .type-post.
$post_classes = str_replace( 'type-', 'tz-type-', $post_classes );
// Wrap post content into <article> tag.
$post_article = sprintf(
'<article id="post-%1$s" class="%2$s">%3$s</article>',
get_the_ID(),
$post_classes,
$post_content
);
// Add Wrapper Div for Post Article.
$post_wrap = sprintf( '<div class="tz-post-wrap">%s</div>', $post_article );
return $post_wrap;
}
/**
* Get Post Image.
*
* @param array $image_size The image size.
*
* @return string Returns the post image.
*/
static function get_post_image( $image_size = 'post-thumbnail' ) {
if ( has_post_thumbnail() ) {
$image = get_the_post_thumbnail( null, $image_size );
} else {
$image = '<img src="' . THEMEZEE_MAGAZINE_BLOCKS_PLUGIN_URL . 'assets/images/default-featured-image.png" class="attachment-full size-full wp-post-image" width="1600" height="1200" alt />';
}
$figure = sprintf(
'<figure class="tz-entry-image entry-image"><a href="%1$s" rel="bookmark">%2$s</a></figure>',
esc_url( get_permalink() ),
$image
);
return $figure;
}
/**
* Get Post Header.
*
* @param array $attributes The block attributes.
*
* @return string Returns the post header.
*/
static function get_post_header( $attributes ) {
$header_content = '';
$show_meta = $attributes['showDate'] || $attributes['showAuthor'] || $attributes['showCategories'] || $attributes['showComments'];
// Show Post Meta?
if ( 'above-title' === $attributes['metaPosition'] && true === $show_meta ) {
$header_content .= self::get_post_meta( $attributes );
}
// Add Title.
$header_content .= self::get_post_title( $attributes );
// Show Post Meta?
if ( 'below-title' === $attributes['metaPosition'] && true === $show_meta ) {
$header_content .= self::get_post_meta( $attributes );
}
// Wrap header content.
$header = sprintf( '<header class="tz-entry-header entry-header">%s</header>', $header_content );
return $header;
}
/**
* Get Post Title.
*
* @param array $attributes The block attributes.
*
* @return string Returns the post title.
*/
static function get_post_title( $attributes ) {
$title = sprintf(
'<h2 class="tz-entry-title entry-title"><a href="%1$s" rel="bookmark">%2$s</a></h2>',
esc_url( get_permalink() ),
esc_html( get_the_title() )
);
return $title;
}
/**
* Get Post Meta.
*
* @param array $attributes The block attributes.
*
* @return string Returns the post meta.
*/
static function get_post_meta( $attributes ) {
$meta_content = '';
// Show Date?
if ( true === $attributes['showDate'] ) {
$meta_content .= self::get_post_date( $attributes );
}
// Show Author?
if ( true === $attributes['showAuthor'] ) {
$meta_content .= self::get_post_author( $attributes );
}
// Show Categories?
if ( true === $attributes['showCategories'] ) {
$meta_content .= self::get_post_categories( $attributes );
}
// Show Comments?
if ( true === $attributes['showComments'] ) {
$meta_content .= self::get_post_comments( $attributes );
}
// Wrap header content.
$postmeta = sprintf( '<div class="tz-entry-meta entry-meta">%s</div>', $meta_content );
return $postmeta;
}
/**
* Get Post Date.
*
* @param array $attributes The block attributes.
*
* @return string Returns the post date.
*/
static function get_post_date( $attributes ) {
// Create date string.
$time_string = sprintf( '<a href="%1$s" title="%2$s" rel="bookmark"><time class="published updated" datetime="%3$s">%4$s</time></a>',
esc_url( get_permalink() ),
esc_attr( get_the_time() ),
esc_attr( get_the_date( 'c' ) ),
esc_html( get_the_date() )
);
// Wrap date.
$date = sprintf( '<span class="tz-meta-date meta-date tz-meta-field">%s</span>', $time_string );
return $date;
}
/**
* Get Post Author.
*
* @param array $attributes The block attributes.
*
* @return string Returns the post author.
*/
static function get_post_author( $attributes ) {
// Create author string.
$author_string = sprintf( '<a class="url fn n" href="%1$s" title="%2$s" rel="author">%3$s</a>',
esc_url( get_author_posts_url( get_the_author_meta( 'ID' ) ) ),
esc_attr( sprintf( esc_html__( 'View all posts by %s', 'themezee-magazine-blocks' ), get_the_author() ) ),
esc_html( get_the_author() )
);
// Wrap author.
$author = sprintf( '<span class="tz-meta-author meta-author tz-meta-field author vcard">%s</span>', $author_string );
return $author;
}
/**
* Get Post Categories.
*
* @param array $attributes The block attributes.
*
* @return string Returns the post categories.
*/
static function get_post_categories( $attributes ) {
// Return early if post has no category.
if ( ! has_category() ) {
return;
}
$category_list = get_the_category_list( '<span class="tz-meta-categories-sep">, </span> ' );
// Wrap categories.
$categories = sprintf( '<span class="tz-meta-categories meta-categories tz-meta-field">%s</span>', $category_list );
return $categories;
}
/**
* Get Post Comments.
*
* @param array $attributes The block attributes.
*
* @return string Returns the post comments.
*/
static function get_post_comments( $attributes ) {
// Return early if post has no comment function.
if ( ! ( comments_open() || get_comments_number() ) ) {
return;
}
// Start Output Buffering.
ob_start();
// Get Comment String.
comments_popup_link(
esc_html__( 'Leave a comment', 'themezee-magazine-blocks' ),
esc_html__( 'One comment', 'themezee-magazine-blocks' ),
esc_html__( '% comments', 'themezee-magazine-blocks' )
);
$comment_string = ob_get_contents();
// End Output Buffering.
ob_end_clean();
// Wrap comments.
$comments = sprintf( '<span class="tz-meta-comments meta-comments tz-meta-field">%s</span>', $comment_string );
return $comments;
}
/**
* Get Post Content.
*
* @param array $attributes The block attributes.
*
* @return string Returns the post content.
*/
static function get_post_content( $attributes ) {
$post_content = '';
// Add Excerpt.
$post_content .= self::get_post_excerpt( $attributes );
// Show Read More link?
if ( '' !== $attributes['moreText'] ) {
$post_content .= self::get_post_read_more_link( $attributes );
}
// Wrap post content.
$content = sprintf( '<div class="tz-entry-content entry-content">%s</div>', $post_content );
return $content;
}
/**
* Get Post Excerpt.
*
* @param array $attributes The block attributes.
*
* @return string Returns the post excerpt.
*/
static function get_post_excerpt( $attributes ) {
$post = get_post();
if ( empty( $post ) ) {
return '';
}
$post_excerpt = $post->post_excerpt;
if ( ! ( $post_excerpt ) ) {
$post_excerpt = $post->post_content;
}
$trimmed_excerpt = esc_html( wp_trim_words( $post_excerpt, $attributes['excerptLength'], '' ) );
// Wrap Excerpt.
$excerpt = sprintf( '<p>%s <span class="tz-excerpt-more">[&hellip;]</span></p>', $trimmed_excerpt );
return $excerpt;
}
/**
* Get Post Read More link.
*
* @param array $attributes The block attributes.
*
* @return string Returns the post read more link.
*/
static function get_post_read_more_link( $attributes ) {
$link = sprintf(
'<p class="tz-read-more read-more"><a href="%1$s" class="tz-more-link more-link" rel="bookmark">%2$s</a></p>',
esc_url( get_permalink() ),
esc_html( $attributes['moreText'] )
);
return $link;
}
}
<?php
/**
* Full file path: includes/blocks/class-themezee-magazine-blocks-vertical.php
* Server-side rendering of the Magazine Vertical Block
*
* @package ThemeZee Magazine Blocks
*/
// Exit if accessed directly.
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
/**
* ThemeZee Magazine Blocks Magazine Vertical Class
*/
class ThemeZee_Magazine_Blocks_Vertical {
/**
* Setup the class
*
* @return void
*/
static function setup() {
// Register Block.
add_action( 'init', array( __CLASS__, 'register_block' ) );
}
/**
* Register block on server.
*
* @return void
*/
static function register_block() {
register_block_type(
'themezee-magazine-blocks/vertical',
array(
'attributes' => array(
'className' => array(
'type' => 'string',
),
'categories' => array(
'type' => 'array',
),
'tags' => array(
'type' => 'string',
),
'author' => array(
'type' => 'string',
),
'numberOfPosts' => array(
'type' => 'number',
'default' => 5,
),
'offset' => array(
'type' => 'number',
'default' => 0,
),
'order' => array(
'type' => 'string',
'default' => 'desc',
),
'orderBy' => array(
'type' => 'string',
'default' => 'date',
),
'imageSize' => array(
'type' => 'string',
'default' => 'full',
),
'thumbnailSize' => array(
'type' => 'string',
'default' => 'full',
),
'metaPosition' => array(
'type' => 'string',
'default' => 'below-title',
),
'showDate' => array(
'type' => 'boolean',
'default' => true,
),
'showAuthor' => array(
'type' => 'boolean',
'default' => true,
),
'showCategories' => array(
'type' => 'boolean',
'default' => false,
),
'showComments' => array(
'type' => 'boolean',
'default' => false,
),
'excerptLength' => array(
'type' => 'number',
'default' => 25,
),
'moreText' => array(
'type' => 'string',
'default' => esc_html__( 'Continue Reading', 'themezee-magazine-blocks' ),
),
),
'render_callback' => array( __CLASS__, 'render_block' ),
'style' => 'themezee-magazine-blocks',
'editor_script' => 'themezee-magazine-blocks',
'editor_style' => 'themezee-magazine-blocks-editor',
)
);
}
/**
* Render block.
*
* @param array $attributes The block attributes.
*
* @return string Returns the block content.
*/
static function render_block( $attributes ) {
// Fetch posts from cache or database.
$posts_query = ThemeZee_Magazine_Blocks_Cache::query_posts( $attributes );
// Set up markup variables.
$highlight_post = '';
$list_posts = '';
// Check if there are posts.
if ( $posts_query->have_posts() ) :
// Get Posts Markup.
while ( $posts_query->have_posts() ) :
$posts_query->the_post();
// Display first post differently.
if ( 0 === $posts_query->current_post ) :
$highlight_post .= ThemeZee_Magazine_Blocks_Template::get_grid_post( $attributes, $attributes['imageSize'] );
else :
$list_posts .= ThemeZee_Magazine_Blocks_Template::get_list_post( $attributes, $attributes['thumbnailSize'], false );
endif;
endwhile;
endif;
// Reset Postdata.
wp_reset_postdata();
// Wrap Highlight Posts.
$highlight_post = sprintf( '<div class="tz-magazine-highlight-post">%s</div>', $highlight_post );
// Wrap Thumbnail Posts.
$list_posts = sprintf( '<div class="tz-magazine-thumbnail-list">%s</div>', $list_posts );
// Set Posts Markup.
$posts_markup = $highlight_post . $list_posts;
// Define Block Content.
$block_content = sprintf( '<div class="tz-magazine-vertical">%s</div>', $posts_markup );
// Get Block Classes.
$block_classes = self::get_block_classes( $attributes );
// Wrap Block Content.
$block = sprintf(
'<div class="%1$s">%2$s</div>',
esc_attr( $block_classes ),
$block_content
);
return $block;
}
/**
* Get Block Classes.
*
* @param array $attributes The block attributes.
*
* @return string Returns the block classes.
*/
static function get_block_classes( $attributes ) {
$classes = 'wp-block-themezee-magazine-blocks-vertical';
$classes .= ' tz-magazine-block';
if ( isset( $attributes['className'] ) ) {
$classes .= ' ' . $attributes['className'];
}
return $classes;
}
}
// Run Class.
ThemeZee_Magazine_Blocks_Vertical::setup();
/**
* Full file path: scr/components/magazine-block.js
* External dependencies
*/
import classnames from 'classnames';
const {
isUndefined,
pickBy,
} = lodash;
/**
* WordPress dependencies
*/
const { compose } = wp.compose;
const { withSelect } = wp.data;
const {
Component,
Fragment,
} = wp.element;
const {
__,
} = wp.i18n;
const {
BlockControls,
InspectorControls,
} = wp.editor;
const {
PanelBody,
Placeholder,
RangeControl,
SelectControl,
Spinner,
TextControl,
ToggleControl,
Toolbar,
} = wp.components;
/**
* Internal dependencies
*/
import CategorySelect from './controls/category-select';
import AuthorSelect from './controls/author-select';
import OrderSelect from './controls/order-select';
import MagazineTemplate from './magazine-template';
/**
* Block Edit Component
*/
class MagazineBlock extends Component {
render() {
const {
attributes,
className,
setAttributes,
latestPosts,
placeholderLabel,
placeholderIcon,
magazineTemplate,
} = this.props;
const {
categories,
tags,
author,
order,
orderBy,
numberOfPosts,
offset,
metaPosition,
showDate,
showAuthor,
showCategories,
showComments,
excerptLength,
moreText,
} = attributes;
const blockClasses = classnames( className, 'tz-magazine-block' );
const blockControls = (
<BlockControls key="controls">
{ this.props.blockControls ? this.props.blockControls : null }
<Toolbar
controls={ [ {
// Font Awesone Plus Solid
icon: 'plus',
title: __( 'Show one post more', 'gt-blocks' ),
onClick: () => setAttributes( { numberOfPosts: numberOfPosts + 1 } ),
}, {
// Font Awesone Minus Solid
icon: 'minus',
title: __( 'Show one post less', 'gt-blocks' ),
onClick: () => {
if ( numberOfPosts > 1 ) {
setAttributes( { numberOfPosts: numberOfPosts - 1 } );
}
},
} ] }
/>
</BlockControls>
);
const inspectorControls = (
<InspectorControls>
<PanelBody title={ __( 'Content Settings', 'themezee-magazine-blocks' ) } initialOpen={ false }>
<CategorySelect
selectedCategoryId={ categories }
onCategoryChange={ ( value ) => setAttributes( { categories: [] !== value ? value : undefined } ) }
/>
<TextControl
label={ __( 'Tags', 'themezee-magazine-blocks' ) }
value={ tags }
onChange={ ( value ) => setAttributes( { tags: '' !== value ? value : undefined } ) }
/>
<AuthorSelect
selectedAuthorId={ author }
onAuthorChange={ ( value ) => setAttributes( { author: '' !== value ? value : undefined } ) }
/>
<OrderSelect
{ ...{ order, orderBy } }
onOrderChange={ ( value ) => setAttributes( { order: value } ) }
onOrderByChange={ ( value ) => setAttributes( { orderBy: value } ) }
/>
<RangeControl
key="tz-number-of-posts-control"
label={ __( 'Number of posts', 'themezee-magazine-blocks' ) }
value={ numberOfPosts }
onChange={ ( value ) => setAttributes( { numberOfPosts: value } ) }
min={ 1 }
max={ 30 }
/>
<RangeControl
key="tz-offset-control"
label={ __( 'Skip Posts', 'themezee-magazine-blocks' ) }
value={ offset }
onChange={ ( value ) => setAttributes( { offset: value } ) }
min={ 0 }
max={ 30 }
/>
</PanelBody>
{ this.props.layoutSettings ? this.props.layoutSettings : null }
<PanelBody title={ __( 'Post Settings', 'themezee-magazine-blocks' ) } initialOpen={ false }>
<SelectControl
label={ __( 'Post Details', 'themezee-magazine-blocks' ) }
value={ metaPosition }
onChange={ ( value ) => setAttributes( { metaPosition: value } ) }
options={ [
{ value: 'above-title', label: __( 'Show above post title', 'themezee-magazine-blocks' ) },
{ value: 'below-title', label: __( 'Show below post title', 'themezee-magazine-blocks' ) },
] }
/>
<ToggleControl
label={ __( 'Display Date', 'gt-blocks' ) }
checked={ !! showDate }
onChange={ () => setAttributes( { showDate: ! showDate } ) }
/>
<ToggleControl
label={ __( 'Display Author', 'gt-blocks' ) }
checked={ !! showAuthor }
onChange={ () => setAttributes( { showAuthor: ! showAuthor } ) }
/>
<ToggleControl
label={ __( 'Display Categories', 'gt-blocks' ) }
checked={ !! showCategories }
onChange={ () => setAttributes( { showCategories: ! showCategories } ) }
/>
<ToggleControl
label={ __( 'Display Comments', 'gt-blocks' ) }
checked={ !! showComments }
onChange={ () => setAttributes( { showComments: ! showComments } ) }
/>
<RangeControl
label={ __( 'Excerpt Length', 'themezee-magazine-blocks' ) }
value={ excerptLength }
onChange={ ( value ) => setAttributes( { excerptLength: value } ) }
min={ 0 }
max={ 100 }
/>
{ excerptLength > 0 && (
<TextControl
label={ __( 'Read More Text', 'themezee-magazine-blocks' ) }
value={ moreText }
onChange={ ( value ) => setAttributes( { moreText: value } ) }
/>
) }
</PanelBody>
</InspectorControls>
);
const hasPosts = Array.isArray( latestPosts ) && latestPosts.length;
if ( ! hasPosts ) {
return (
<Fragment>
{ blockControls }
{ inspectorControls }
<Placeholder
icon={ placeholderIcon }
label={ placeholderLabel }
className="tz-posts-placeholder"
>
{ ! Array.isArray( latestPosts ) ?
<Spinner /> :
__( 'No posts found. You may have to reconfigure your content settings.', 'themezee-magazine-blocks' )
}
</Placeholder>
</Fragment>
);
}
// Removing posts from display should be instant.
const displayPosts = latestPosts.length > numberOfPosts ?
latestPosts.slice( 0, numberOfPosts ) :
latestPosts;
return (
<Fragment>
{ blockControls }
{ inspectorControls }
<div className={ blockClasses }>
<MagazineTemplate
posts={ displayPosts }
attributes={ attributes }
template={ magazineTemplate }
/>
</div>
</Fragment>
);
}
}
export default compose( [
withSelect( ( select, props ) => {
const { categories, tags, author, numberOfPosts, order, orderBy, offset } = props.attributes;
const { getEntityRecords } = select( 'core' );
// Retrieve Tag IDs from Tag names.
let tagsIDs;
if ( ! ( ! tags || 0 === tags.length ) ) {
const tagsObj = getEntityRecords( 'taxonomy', 'post_tag', { per_page: -1, slug: tags } );
if ( tagsObj ) {
tagsIDs = Object.keys( tagsObj ).reduce( ( str, key ) => str + tagsObj[ key ].id + ',', '' );
tagsIDs = tagsIDs.slice( 0, -1 );
}
}
const tagsQuery = '' !== tagsIDs ? { tags: tagsIDs } : undefined;
// Query Posts.
const latestPostsQuery = pickBy( {
categories,
...tagsQuery,
author,
order,
orderby: orderBy,
per_page: numberOfPosts,
offset,
}, ( value ) => ! isUndefined( value ) );
return {
latestPosts: getEntityRecords( 'postType', 'post', latestPostsQuery ),
};
} ),
] )( MagazineBlock );
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment