-
Notifications
You must be signed in to change notification settings - Fork 9
feat(block): add block version of the republish button #320
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Draft
rbcorrales
wants to merge
15
commits into
trunk
Choose a base branch
from
feat/republish-button-block
base: trunk
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Draft
Changes from all commits
Commits
Show all changes
15 commits
Select commit
Hold shift + click to select a range
c902770
build: add webpack build pipeline with newspack-scripts
rbcorrales d54ddb7
refactor: shared modal flag and remove inline onclick from copy button
rbcorrales 30606cf
feat(block): add block.json metadata and base styles
rbcorrales a7a3530
feat(block): add editor component with block registration
rbcorrales f9feea1
feat(block): add PHP block class with server-side rendering
rbcorrales 395099b
feat(block): add frontend modal JS for block trigger
rbcorrales 162cbb9
chore: raise minimum WP version to 6.0 for block support
rbcorrales 262254e
fix(block): address review findings from 12 parallel code reviewers
rbcorrales 1aace67
fix(block): address remaining review findings
rbcorrales 73620aa
fix(block): apply wrapper attributes to outer div for correct anchor …
rbcorrales 1da6b7f
fix: resolve PHPCS, eslint plugin, and test failures
rbcorrales 529045f
fix(block): address Copilot review feedback
rbcorrales 642d9b8
fix: resolve JS lint errors in edit.js and view.js
rbcorrales f228d76
fix: update widget test assertion and register block in test setup
rbcorrales 1e18f1c
fix: resolve test failures and load composer autoloader in bootstrap
rbcorrales File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or 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 |
|---|---|---|
|
|
@@ -35,3 +35,7 @@ contributing.md | |
| docs | ||
| release.sh | ||
| release | ||
| src/**/*.js | ||
| src/**/*.jsx | ||
| src/**/*.scss | ||
| webpack.config.js | ||
This file contains hidden or 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 |
|---|---|---|
|
|
@@ -8,3 +8,4 @@ node_modules/ | |
| release/ | ||
| vendor | ||
| .phpunit.result.cache | ||
| dist/ | ||
This file contains hidden or 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
This file contains hidden or 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,193 @@ | ||
| <?php | ||
| /** | ||
| * Republish Button Block. | ||
| * | ||
| * @package Republication_Tracker_Tool | ||
| */ | ||
|
|
||
| // Exit if accessed directly. | ||
| defined( 'ABSPATH' ) || exit; | ||
|
|
||
| /** | ||
| * Republish Button Block class. | ||
| */ | ||
| final class Republication_Tracker_Tool_Republish_Button_Block { | ||
|
|
||
| /** | ||
| * Initialize the block. | ||
| */ | ||
| public static function init() { | ||
| add_action( 'init', [ __CLASS__, 'register_block' ] ); | ||
| } | ||
|
|
||
| /** | ||
| * Register the block. | ||
| * | ||
| * On block themes the block is fully available. On classic themes it is | ||
| * still registered (so existing content does not become an "unknown block") | ||
| * but hidden from the inserter. | ||
| */ | ||
| public static function register_block() { | ||
| $args = [ | ||
| 'render_callback' => [ __CLASS__, 'render_block' ], | ||
| ]; | ||
|
|
||
| if ( function_exists( 'wp_is_block_theme' ) && ! wp_is_block_theme() ) { | ||
| $args['supports'] = [ | ||
| 'inserter' => false, | ||
| ]; | ||
| } | ||
|
|
||
| register_block_type_from_metadata( | ||
| REPUBLICATION_TRACKER_TOOL_PATH . 'src/blocks/republish-button', | ||
| $args | ||
| ); | ||
| } | ||
|
|
||
| /** | ||
| * Render the block on the frontend. | ||
| * | ||
| * @param array $attrs Block attributes. | ||
| * @return string Rendered block HTML. | ||
| */ | ||
| public static function render_block( $attrs ) { | ||
| global $post; | ||
|
|
||
| // Guard: only render on singular views. | ||
| if ( ! is_singular() || ! $post instanceof \WP_Post ) { | ||
| return ''; | ||
| } | ||
|
|
||
| // Guard: check allowed post types. | ||
| $allowed_post_types = (array) apply_filters( 'republication_tracker_tool_post_types', [ 'post' ] ); | ||
| if ( ! in_array( get_post_type( $post ), $allowed_post_types, true ) ) { | ||
| return ''; | ||
| } | ||
|
|
||
| // Guard: check if widget is hidden for this post (same filter as the widget). | ||
| $hide = apply_filters( | ||
| 'hide_republication_widget', | ||
| get_post_meta( $post->ID, 'republication-tracker-tool-hide-widget', true ), | ||
| $post | ||
| ); | ||
| if ( true == $hide ) { // phpcs:ignore Universal.Operators.StrictComparisons.LooseEqual | ||
| return ''; | ||
| } | ||
|
|
||
| // Translated defaults (block.json defaults are not translatable). | ||
| $default_attrs = [ | ||
| 'buttonText' => __( 'Republish This Story', 'republication-tracker-tool' ), | ||
| 'message' => __( 'Republish our articles for free, online or in print, under a Creative Commons license.', 'republication-tracker-tool' ), | ||
| 'displayMode' => 'modal', | ||
| ]; | ||
| $attrs = wp_parse_args( $attrs, $default_attrs ); | ||
|
|
||
| // Validate displayMode against allowed values. | ||
| if ( ! in_array( $attrs['displayMode'], [ 'modal', 'page' ], true ) ) { | ||
| $attrs['displayMode'] = 'modal'; | ||
| } | ||
|
|
||
| // Fall back to translated default when attribute is empty string. | ||
| $button_text = '' === trim( (string) $attrs['buttonText'] ) ? $default_attrs['buttonText'] : $attrs['buttonText']; | ||
| $message_text = '' === trim( (string) $attrs['message'] ) ? $default_attrs['message'] : $attrs['message']; | ||
| $display_mode = $attrs['displayMode']; | ||
|
|
||
| // License badge. | ||
| $license_key = get_option( 'republication_tracker_tool_license', REPUBLICATION_TRACKER_TOOL_DEFAULT_LICENSE ); | ||
| $using_license = isset( REPUBLICATION_TRACKER_TOOL_LICENSES[ $license_key ] ); | ||
|
|
||
| // Block wrapper attributes go on the outer div (anchor, alignment, layout, block supports). | ||
| $wrapper_attributes = get_block_wrapper_attributes(); | ||
|
|
||
| // Start building output. | ||
| $html = '<div ' . $wrapper_attributes . '>'; | ||
|
|
||
| // Message. | ||
| $html .= '<p class="wp-block-republication-tracker-tool-republish-button__message">' . wp_kses_post( $message_text ) . '</p>'; | ||
|
|
||
| // Button or link (inherits colors from wrapper via CSS). | ||
| $button_class = 'wp-block-republication-tracker-tool-republish-button__button'; | ||
| if ( 'page' === $display_mode ) { | ||
| $endpoint = apply_filters( 'republication_tracker_tool_endpoint', 'republish' ); | ||
| $republish_url = home_url( '/' . $endpoint . wp_make_link_relative( get_permalink( $post->ID ) ) ); | ||
| $html .= '<a class="' . esc_attr( $button_class ) . '" href="' . esc_url( $republish_url ) . '">' . esc_html( $button_text ) . '</a>'; | ||
rbcorrales marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| } else { | ||
| $html .= '<button class="' . esc_attr( $button_class ) . '" data-modal-trigger="republish">' . esc_html( $button_text ) . '</button>'; | ||
| } | ||
|
|
||
| // License badge. | ||
| if ( $using_license ) { | ||
| $html .= sprintf( | ||
| '<p><a class="license" rel="noreferrer license" target="_blank" href="%s"><img alt="%s" style="border-width:0" src="%s" /></a></p>', | ||
| esc_url( REPUBLICATION_TRACKER_TOOL_LICENSES[ $license_key ]['url'] ), | ||
| esc_html__( 'Creative Commons License', 'republication-tracker-tool' ), | ||
| esc_url( plugin_dir_url( __DIR__ ) . 'assets/img/' . $license_key . '.png' ) | ||
| ); | ||
| } | ||
|
|
||
| $html .= '</div>'; | ||
|
|
||
| // Modal (only for modal mode, only once per page). | ||
| if ( 'modal' === $display_mode ) { | ||
| self::enqueue_modal_assets(); | ||
|
|
||
| if ( ! Republication_Tracker_Tool::$modal_rendered ) { | ||
| Republication_Tracker_Tool::$modal_rendered = true; | ||
|
|
||
| $is_amp = false; // Block themes do not support AMP. | ||
| $modal_content_path = REPUBLICATION_TRACKER_TOOL_PATH . 'includes/shareable-content.php'; | ||
|
|
||
| ob_start(); | ||
| ?> | ||
| <div id="republication-tracker-tool-modal" style="display:none;" data-postid="<?php echo esc_attr( $post->ID ); ?>" data-pluginsdir="<?php echo esc_attr( plugins_url() ); ?>" role="dialog" aria-modal="true" aria-labelledby="republish-modal-label"> | ||
| <?php include $modal_content_path; ?> | ||
| </div> | ||
| <?php | ||
| $html .= ob_get_clean(); | ||
| } | ||
| } | ||
|
|
||
| return $html; | ||
| } | ||
|
|
||
| /** | ||
| * Enqueue modal-specific assets. | ||
| */ | ||
| private static function enqueue_modal_assets() { | ||
| // Modal styles (same handle as widget for deduplication). | ||
| wp_enqueue_style( | ||
| 'republication-tracker-tool-css', | ||
| REPUBLICATION_TRACKER_TOOL_URL . 'assets/widget.css', | ||
| [], | ||
| REPUBLICATION_TRACKER_TOOL_VERSION | ||
| ); | ||
|
|
||
| // Clipboard utilities (shared with widget). | ||
| wp_enqueue_script( | ||
| 'republication-tracker-tool-clipboard-utils', | ||
| REPUBLICATION_TRACKER_TOOL_URL . 'assets/clipboard-utils.js', | ||
| [], | ||
| REPUBLICATION_TRACKER_TOOL_VERSION, | ||
| true | ||
| ); | ||
|
|
||
| // Block frontend script. | ||
| $asset_file = REPUBLICATION_TRACKER_TOOL_PATH . 'dist/republish-button-view.asset.php'; | ||
| $asset = file_exists( $asset_file ) | ||
| ? include $asset_file | ||
| : [ | ||
| 'dependencies' => [], | ||
| 'version' => REPUBLICATION_TRACKER_TOOL_VERSION, | ||
| ]; | ||
|
|
||
| wp_enqueue_script( | ||
| 'republication-tracker-tool-republish-button-view', | ||
| REPUBLICATION_TRACKER_TOOL_URL . 'dist/republish-button-view.js', | ||
| array_merge( $asset['dependencies'], [ 'republication-tracker-tool-clipboard-utils' ] ), | ||
| $asset['version'], | ||
| true | ||
| ); | ||
| } | ||
| } | ||
|
|
||
| Republication_Tracker_Tool_Republish_Button_Block::init(); | ||
This file contains hidden or 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
This file contains hidden or 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
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.