Skip to content

Commit

Permalink
Featured Lessons only on front page (#2588)
Browse files Browse the repository at this point in the history
* Add featured lesson post meta field and sidebar control

* 💄 Fix eslint

* Add Lesson Grid block variation

* Update front page to have featured lessons only
  • Loading branch information
adamwoodnz authored Jul 3, 2024
1 parent 9d17df0 commit 4eaec88
Show file tree
Hide file tree
Showing 8 changed files with 274 additions and 5 deletions.
47 changes: 47 additions & 0 deletions wp-content/plugins/wporg-learn/inc/post-meta.php
Original file line number Diff line number Diff line change
Expand Up @@ -27,11 +27,32 @@
* Register all post meta keys.
*/
function register() {
register_lesson_meta();
register_lesson_plan_meta();
register_workshop_meta();
register_misc_meta();
}

/**
* Register post meta keys for lessons.
*/
function register_lesson_meta() {
register_post_meta(
'lesson',
'_lesson_featured',
array(
'description' => __( 'Whether the lesson is featured.', 'wporg-learn' ),
'type' => 'string',
'single' => true,
'sanitize_callback' => 'sanitize_text_field',
'show_in_rest' => true,
'auth_callback' => function( $allowed, $meta_key, $post_id ) {
return current_user_can( 'edit_post', $post_id );
},
),
);
}

/**
* Register post meta keys for lesson plans.
*/
Expand Down Expand Up @@ -613,6 +634,7 @@ function render_locales_list() {
function enqueue_editor_assets() {
enqueue_expiration_date_assets();
enqueue_language_meta_assets();
enqueue_lesson_featured_meta_assets();
enqueue_duration_meta_assets();
}

Expand Down Expand Up @@ -669,6 +691,31 @@ function enqueue_language_meta_assets() {
}
}

/**
* Enqueue scripts for the featured lesson meta block.
*/
function enqueue_lesson_featured_meta_assets() {
global $typenow;

if ( 'lesson' === $typenow ) {
$script_asset_path = get_build_path() . 'lesson-featured-meta.asset.php';
if ( ! file_exists( $script_asset_path ) ) {
wp_die( 'You need to run `yarn start` or `yarn build` to build the required assets.' );
}

$script_asset = require( $script_asset_path );
wp_enqueue_script(
'wporg-learn-lesson-featured-meta',
get_build_url() . 'lesson-featured-meta.js',
$script_asset['dependencies'],
$script_asset['version'],
true
);

wp_set_script_translations( 'wporg-learn-lesson-featured-meta', 'wporg-learn' );
}
}

/**
* Enqueue scripts for the duration meta block.
*/
Expand Down
42 changes: 42 additions & 0 deletions wp-content/plugins/wporg-learn/js/lesson-featured-meta/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
/**
* WordPress dependencies
*/
import { CheckboxControl, PanelRow } from '@wordpress/components';
import { useDispatch, useSelect } from '@wordpress/data';
import { PluginDocumentSettingPanel } from '@wordpress/edit-post';
import { useState } from '@wordpress/element';
import { __ } from '@wordpress/i18n';
import { registerPlugin } from '@wordpress/plugins';

const FEATURED = 'featured';

const LessonFeaturedMeta = () => {
const postMetaData = useSelect( ( select ) => select( 'core/editor' ).getEditedPostAttribute( 'meta' ) || {} );
const { editPost } = useDispatch( 'core/editor' );
const [ lessonFeatured, setLessonFeatured ] = useState( postMetaData?._lesson_featured === FEATURED );

return (
<PluginDocumentSettingPanel title={ __( 'Featured Lesson', 'wporg-learn' ) }>
<PanelRow>
<CheckboxControl
label={ __( 'Feature this lesson', 'wporg-learn' ) }
checked={ lessonFeatured }
onChange={ ( newLessonFeatured ) => {
setLessonFeatured( newLessonFeatured );

editPost( {
meta: {
...postMetaData,
_lesson_featured: newLessonFeatured ? FEATURED : '',
},
} );
} }
/>
</PanelRow>
</PluginDocumentSettingPanel>
);
};

registerPlugin( 'wporg-learn-lesson-featured-meta', {
render: LessonFeaturedMeta,
} );
1 change: 1 addition & 0 deletions wp-content/plugins/wporg-learn/webpack.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ config.entry = {
'duration-meta': './js/duration-meta/index.js',
'expiration-date': './js/expiration-date/index.js',
'lesson-count': './js/lesson-count/src/index.js',
'lesson-featured-meta': './js/lesson-featured-meta/index.js',
'workshop-application-form': './js/workshop-application-form/src/index.js',
'workshop-details': './js/workshop-details/src/index.js',
event: './js/event.js',
Expand Down
1 change: 1 addition & 0 deletions wp-content/themes/pub/wporg-learn-2024/functions.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
require_once __DIR__ . '/src/course-grid/index.php';
require_once __DIR__ . '/src/learning-pathway-cards/index.php';
require_once __DIR__ . '/src/learning-pathway-header/index.php';
require_once __DIR__ . '/src/lesson-grid/index.php';
require_once __DIR__ . '/src/search-results-context/index.php';
require_once __DIR__ . '/src/upcoming-online-workshops/index.php';
require_once __DIR__ . '/src/sensei-meta-list/index.php';
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@
<!-- /wp:query -->

<!-- wp:heading {"style":{"spacing":{"margin":{"top":"var:preset|spacing|60","bottom":"var:preset|spacing|10"}}}} -->
<h2 class="wp-block-heading" style="margin-top:var(--wp--preset--spacing--60);margin-bottom:var(--wp--preset--spacing--10)"><?php esc_html_e( 'Lessons', 'wporg-learn' ); ?></h2>
<h2 class="wp-block-heading" style="margin-top:var(--wp--preset--spacing--60);margin-bottom:var(--wp--preset--spacing--10)"><?php esc_html_e( 'Featured Lessons', 'wporg-learn' ); ?></h2>
<!-- /wp:heading -->

<!-- wp:group {"style":{"spacing":{"margin":{"top":"0","bottom":"var:preset|spacing|40"}}},"layout":{"type":"flex","flexWrap":"wrap","justifyContent":"space-between"}} -->
Expand All @@ -73,13 +73,13 @@
</div>
<!-- /wp:group -->

<!-- wp:query {"className":"wporg-learn-card-grid","queryId":1,"query":{"perPage":"6","pages":0,"offset":0,"postType":"lesson","order":"desc","orderBy":"date","author":"","search":"","exclude":[],"sticky":"","inherit":false,"parents":[]}} -->
<div class="wp-block-query wporg-learn-card-grid">

<!-- wp:query {"queryId":1,"query":{"perPage":6,"postType":"lesson","lessonFeatured":true},"namespace":"wporg-learn/lesson-grid","align":"wide","className":"wporg-learn-lesson-grid wporg-learn-card-grid"} -->
<div class="wp-block-query alignwide wporg-learn-lesson-grid wporg-learn-card-grid">
<!-- wp:post-template {"style":{"spacing":{"blockGap":"var:preset|spacing|50"}},"layout":{"type":"grid","columnCount":null,"minimumColumnWidth":"330px"}} -->

<!-- wp:template-part {"slug":"card-lesson-h3","className":"has-display-contents"} /-->

<!-- /wp:post-template -->

<!-- wp:query-no-results -->
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"name": "wporg-learn/lesson-grid",
"title": "Learn Lesson Grid",
"description": "A query loop block variation which displays a cards grid of lessons, filterable by the 'featured' lesson post meta.",
"textdomain": "wporg-learn",
"editorScript": "file:./index.js"
}
86 changes: 86 additions & 0 deletions wp-content/themes/pub/wporg-learn-2024/src/lesson-grid/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
import { registerBlockVariation } from '@wordpress/blocks';
import { addFilter } from '@wordpress/hooks';
import { InspectorControls } from '@wordpress/block-editor';
import { CheckboxControl, PanelBody } from '@wordpress/components';
import { __ } from '@wordpress/i18n';

const VARIATION_NAME = 'wporg-learn/lesson-grid';

registerBlockVariation( 'core/query', {
name: VARIATION_NAME,
title: __( 'Learn Lesson Grid', 'wporg-learn' ),
icon: {
src: (
<svg width="24" height="24" fill="none" xmlns="http://www.w3.org/2000/svg" size="24">
<path
fillRule="evenodd"
clipRule="evenodd"
d="M9 9.5H6a.5.5 0 0 1-.5-.5V6a.5.5 0 0 1 .5-.5h3a.5.5 0 0 1 .5.5v3a.5.5 0 0 1-.5.5ZM6 11h3a2 2 0 0 0 2-2V6a2 2 0 0 0-2-2H6a2 2 0 0 0-2 2v3a2 2 0 0 0 2 2Zm12-1.5h-3a.5.5 0 0 1-.5-.5V6a.5.5 0 0 1 .5-.5h3a.5.5 0 0 1 .5.5v3a.5.5 0 0 1-.5.5ZM15 11h3a2 2 0 0 0 2-2V6a2 2 0 0 0-2-2h-3a2 2 0 0 0-2 2v3a2 2 0 0 0 2 2ZM4 14.5h7V16H4v-1.5Zm16 0h-7V16h7v-1.5Zm-16 4h5V20H4v-1.5Zm14 0h-5V20h5v-1.5Z"
fill="#1E1E1E"
></path>
</svg>
),
},
description: __( 'Displays a cards grid of lessons.', 'wporg-learn' ),
attributes: {
className: 'wporg-learn-lesson-grid wporg-learn-card-grid',
namespace: VARIATION_NAME,
query: {
perPage: 6,
postType: 'lesson',
lessonFeatured: false,
},
align: 'wide',
},
isActive: ( { namespace, query } ) => namespace === VARIATION_NAME && query.postType === 'lesson',
innerBlocks: [
[
'core/post-template',
{
style: { spacing: { blockGap: 'var:preset|spacing|50' } },
layout: { type: 'grid', columnCount: null, minimumColumnWidth: '330px' },
},
[ [ 'core/template-part', { slug: 'card-lesson', className: 'has-display-contents' }, [] ] ],
],
[ 'core/query-no-results' ],
],
} );

const isLessonGridVariation = ( { attributes: { namespace } } ) => namespace && namespace === VARIATION_NAME;

const LessonGridControls = ( {
props: {
attributes: { query },
setAttributes,
},
} ) => (
<PanelBody title={ __( 'Featured', 'wporg-learn' ) }>
<CheckboxControl
label={ __( 'Featured only', 'wporg-learn' ) }
checked={ query.lessonFeatured || false }
onChange={ ( checked ) => {
setAttributes( {
query: {
...query,
lessonFeatured: checked,
},
} );
} }
/>
</PanelBody>
);

export const withLessonGridControls = ( BlockEdit ) => ( props ) => {
return isLessonGridVariation( props ) ? (
<>
<BlockEdit { ...props } />
<InspectorControls>
<LessonGridControls props={ props } />
</InspectorControls>
</>
) : (
<BlockEdit { ...props } />
);
};

addFilter( 'editor.BlockEdit', 'core/query', withLessonGridControls );
85 changes: 85 additions & 0 deletions wp-content/themes/pub/wporg-learn-2024/src/lesson-grid/index.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
<?php
namespace WordPressdotorg\Theme\Learn_2024\Lesson_Grid;

add_action( 'enqueue_block_editor_assets', __NAMESPACE__ . '\enqueue_lesson_grid_assets' );

add_filter( 'pre_render_block', __NAMESPACE__ . '\modify_lesson_query', 10, 2 );
add_filter( 'rest_lesson_query', __NAMESPACE__ . '\modify_lesson_rest_query', 10, 2 );

/**
* Enqueue lesson grid assets.
*
* @throws Error If the build files are not found.
*/
function enqueue_lesson_grid_assets() {
$script_asset_path = get_stylesheet_directory() . '/build/lesson-grid/index.asset.php';
if ( ! is_readable( $script_asset_path ) ) {
throw new Error(
'You need to run `npm start` or `npm run build` for the "wporg-learn/lesson-grid" block first.'
);
}

$script_asset = require $script_asset_path;
wp_enqueue_script(
'wporg-learn-lesson-grid',
get_stylesheet_directory_uri() . '/build/lesson-grid/index.js',
$script_asset['dependencies'],
$script_asset['version'],
true
);
}

/**
* Modify the lesson query to add the featured lesson meta query if set.
*
* @param mixed $pre_render The pre-render value.
* @param mixed $parsed_block The parsed block value.
* @return mixed The modified lesson query.
*/
function modify_lesson_query( $pre_render, $parsed_block ) {
if ( isset( $parsed_block['attrs']['namespace'] ) && 'wporg-learn/lesson-grid' === $parsed_block['attrs']['namespace']
) {
add_filter(
'query_loop_block_query_vars',
function( $query, $block ) use ( $parsed_block ) {
if ( 'lesson' !== $query['post_type'] || ! isset( $parsed_block['attrs']['query']['lessonFeatured'] ) ) {
return $query;
}

$lesson_featured = $parsed_block['attrs']['query']['lessonFeatured'];

if ( true === $lesson_featured ) {
$query['meta_key'] = '_lesson_featured';
$query['meta_value'] = 'featured';
}

return $query;
},
10,
2
);
}

return $pre_render;
}

/**
* Modify the lesson REST query to add the featured lesson meta query if set.
*
* @param array $args The query arguments.
* @param WP_REST_Request $request The REST request object.
* @return array The modified query arguments.
*/
function modify_lesson_rest_query( $args, $request ) {
$lesson_featured = $request->get_param( 'lessonFeatured' );

if ( 'true' === $lesson_featured ) {
$args['meta_query'][] = array(
'key' => '_lesson_featured',
'value' => 'featured',
'compare' => '=',
);
}

return $args;
}

0 comments on commit 4eaec88

Please sign in to comment.