Skip to content
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

Feature: Show/Hide Unsynced/Synced Patterns - Fix Preview Button in Block Editor #34

Merged
merged 3 commits into from
Dec 18, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions build/dlx-pw-fancybox-rtl.css

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion build/dlx-pw-fancybox.asset.php
Original file line number Diff line number Diff line change
@@ -1 +1 @@
<?php return array('dependencies' => array(), 'version' => '1472e41936552f67aa2d');
<?php return array('dependencies' => array(), 'version' => 'bad5a743eede878200a1');
2 changes: 1 addition & 1 deletion build/dlx-pw-fancybox.css

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion build/dlx-pw-fancybox.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion build/dlx-pw-preview.asset.php
Original file line number Diff line number Diff line change
@@ -1 +1 @@
<?php return array('dependencies' => array('react', 'wp-i18n', 'wp-plugins'), 'version' => 'e4831e8d3fc819aefa57');
<?php return array('dependencies' => array('wp-data', 'wp-editor', 'wp-i18n', 'wp-plugins'), 'version' => '7b290f09beaf54ea94a4');
2 changes: 1 addition & 1 deletion build/dlx-pw-preview.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion build/index.asset.php
Original file line number Diff line number Diff line change
@@ -1 +1 @@
<?php return array('dependencies' => array('react', 'wp-block-editor', 'wp-blocks', 'wp-components', 'wp-compose', 'wp-data', 'wp-i18n'), 'version' => '8acc3b91df9514a84ffc');
<?php return array('dependencies' => array('react', 'wp-block-editor', 'wp-blocks', 'wp-components', 'wp-compose', 'wp-data', 'wp-i18n'), 'version' => 'fb0b42dfb9db277c7e2c');
2 changes: 1 addition & 1 deletion build/index.js

Large diffs are not rendered by default.

14,209 changes: 5,704 additions & 8,505 deletions package-lock.json

Large diffs are not rendered by default.

4 changes: 3 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,9 @@
"@wordpress/eslint-plugin": "^12.8.0",
"@wordpress/i18n": "^4.11.0",
"@wordpress/icons": "^9.36.0",
"@wordpress/scripts": "^26.16.0",
"@wordpress/interface": "^8.3.0",
"@wordpress/scripts": "^30.7.0",
"ajv": "^8.17.1",
"axios": "^1.6.1",
"babel-plugin-macros": "^3.1.0",
"classnames": "^2.3.1",
Expand Down
4 changes: 2 additions & 2 deletions pattern-wrangler.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
* Plugin Name: Pattern Wrangler
* Plugin URI: https://dlxplugins.com/plugins/pattern-wrangler/
* Description: Manage your block patterns.
* Version: 1.1.2
* Version: 1.2.0
* Requires at least: 6.5
* Requires PHP: 7.2
* Author: DLX Plugins
Expand All @@ -18,7 +18,7 @@

namespace DLXPlugins\PatternWrangler;

define( 'DLXPW_PATTERN_WRANGLER_VERSION', '1.1.2' );
define( 'DLXPW_PATTERN_WRANGLER_VERSION', '1.2.0' );
define( 'DLXPW_PATTERN_WRANGLER_FILE', __FILE__ );

// Support for site-level autoloading.
Expand Down
15 changes: 15 additions & 0 deletions php/Functions.php
Original file line number Diff line number Diff line change
Expand Up @@ -180,6 +180,21 @@ function ( $a, $b ) {
);
}

/**
* Check if a pattern is synced.
*
* @param int $pattern_id The pattern ID.
*
* @return bool true if synced, false if not.
*/
public static function is_pattern_synced( $pattern_id ) {
$synced = get_post_meta( $pattern_id, 'wp_pattern_sync_status', true );
if ( 'unsynced' === $synced ) {
return false;
}
return true;
}

/**
* Get preview URL for previewing a pattern.
*
Expand Down
2 changes: 2 additions & 0 deletions php/Options.php
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,8 @@ public static function get_defaults() {
'hideRemotePatterns' => false,
'hideThemePatterns' => false,
'hidePluginPatterns' => false,
'hideCoreSyncedPatterns' => false,
'hideCoreUnsyncedPatterns' => false,
'disablePatternImporterBlock' => false,
'categories' => array(),
'allowFrontendPatternPreview' => true,
Expand Down
88 changes: 87 additions & 1 deletion php/Patterns.php
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,9 @@ public function run() {
// Deregister any patterns that are uncategorized.
add_action( 'init', array( $this, 'maybe_deregister_uncategorized_patterns' ), 1003 );

// Deregister any patterns that are not synced.
add_action( 'init', array( $this, 'maybe_deregister_unsynced_patterns' ), 1004 );

// Deregister all pattenrs if all patterns are disabled.
add_action( 'init', array( $this, 'maybe_deregister_all_patterns' ), 2000 );

Expand Down Expand Up @@ -115,6 +118,47 @@ public function run() {
add_action( 'init', array( $this, 'remove_core_patterns' ), 9 );
remove_action( 'init', '_register_core_block_patterns_and_categories' );
}

// Add any admin notices to the patterns post type list view.
add_action( 'admin_notices', array( $this, 'add_admin_notices' ) );
}

/**
* Add admin notices to the patterns post type list view.
*/
public function add_admin_notices() {
$options = Options::get_options();
$hide_core_synced_patterns = (bool) $options['hideCoreSyncedPatterns'];
$hide_core_unsynced_patterns = (bool) $options['hideCoreUnsyncedPatterns'];
if ( $hide_core_synced_patterns && $hide_core_unsynced_patterns ) {
?>
<div class="notice notice-warning">
<p><?php esc_html_e( 'Both synced and unsynced patterns are hidden. Users will not be able to use any of these patterns in the block editor.', 'pattern-wrangler' ); ?></p>
</div>
<?php
return;
} elseif ( $hide_core_synced_patterns ) {
?>
<div class="notice notice-warning">
<p><?php esc_html_e( 'Synced patterns are hidden. Users will not be able to use synced patterns in the block editor.', 'pattern-wrangler' ); ?></p>
</div>
<?php
}
if ( $hide_core_unsynced_patterns ) {
?>
<div class="notice notice-warning">
<p><?php esc_html_e( 'Unsynced patterns are hidden. Users will not be able to use unsynced patterns in the block editor.', 'pattern-wrangler' ); ?></p>
</div>
<?php
}
}

/**
* Deregister any patterns that are not synced.
*/
public function maybe_deregister_unsynced_patterns() {
$options = Options::get_options();
$hide_core_unsynced_patterns = (bool) $options['hideCoreUnsyncedPatterns'];
}

/**
Expand Down Expand Up @@ -492,13 +536,55 @@ public function modify_blocks_rest_query( $args, $request ) {
// Get options.
$options = Options::get_options();

$hide_all_patterns = (bool) $options['hideAllPatterns'];
$hide_all_patterns = (bool) $options['hideAllPatterns'];
$hide_core_synced_patterns = (bool) $options['hideCoreSyncedPatterns'];
$hide_core_unsynced_patterns = (bool) $options['hideCoreUnsyncedPatterns'];

// Exit early if not enabled.
if ( $hide_all_patterns ) {
$args['post__in'] = array( -1 ); // -1 so no patterns are returned.
return $args;
}

// Hide all synced patterns.
if ( $hide_core_synced_patterns ) {
if ( ! isset( $args['meta_query'] ) ) {
$args['meta_query'] = array();
}
$args['meta_query'] = array(
'relation' => 'AND',
array(
'key' => 'wp_pattern_sync_status',
'compare' => 'EXISTS',
),
array(
'key' => 'wp_pattern_sync_status',
'value' => 'unsynced',
'compare' => '=',
),
);
}

// Hide all unsynced patterns.
if ( $hide_core_unsynced_patterns ) {
$args['meta_query'] = array(
'relation' => 'OR',
array(
'key' => 'wp_pattern_sync_status',
'value' => 'unsynced',
'compare' => '!=',
),
array(
'key' => 'wp_pattern_sync_status',
'compare' => 'NOT EXISTS',
),
);
}

// If both synced and unsynced patterns are hidden, hide all meta key matches.
if ( $hide_core_synced_patterns && $hide_core_unsynced_patterns ) {
$args['post__in'] = array( -1 );
}
return $args;
}

Expand Down
56 changes: 40 additions & 16 deletions readme.txt
Original file line number Diff line number Diff line change
@@ -1,25 +1,29 @@
=== Pattern Wrangler - Manage Reusable Blocks and Patterns ===
=== Pattern Wrangler - Manage WordPress Block Patterns Effortlessly ===
Contributors: ronalfy
Tags: patterns, manage, shortcode, reusable, block
Tags: patterns, reusable blocks, block editor, shortcode, block management
Requires at least: 6.5
Tested up to: 6.7
Requires PHP: 7.2
Stable tag: 1.1.2
Stable tag: 1.2.0
License: GPLv2 or later
License URI: https://www.gnu.org/licenses/gpl-2.0.html

Manage your block patterns efficiently with Pattern Wrangler.

== Description ==

Pattern Wrangler enhances your experience with WordPress block patterns by adding a few features that let you:
Pattern Wrangler makes managing WordPress block patterns simple and efficient, with features that cater to both beginners and advanced users. Whether you're organizing patterns for a complex site, a hybrid setup, or just hiding ones you don't need, Pattern Wrangler has you covered.

* Hide All Patterns - If you need to hide patterns completely from the block editor, you can do so with a single click.
* Hide Core and Remote Patterns - If you only want to show patterns you've created, you can hide all core and remote patterns.
* Hide Theme and Plugin Patterns - If you only want to show patterns you've created, you can hide all patterns from themes and plugins.
* Map and Rename Registered Categories - If you have a lot of patterns, you can map them to categories and rename the categories to something more meaningful.
* Output Patterns With a Shortcode - If you want to output a pattern in a page builder or widget, you can do so with a shortcode. This is compatible with most block plugins.
* Copy Patterns From Site to Site - If you have a post on one site, you can copy it over, including the images, using the Pattern Importer block.
Here are the major features:

* **Hide All Patterns** - Completely hide patterns from the block editor in one click. This also hides the Patterns menu item.
* **Selective Hiding** - Hide core, remote, theme, or plugin patterns while keeping your custom patterns visible. You can also hide synced and unsynced patterns together or separately.
* **Category Management** - Disable, map, and rename registered categories from themes and plugins for better organization. This will help you keep local and registered patterns organized together.
* **Output Patterns Anywhere** - Use a shortcode to display local patterns in page builders, widgets, your theme,or other blocks.
* **Pattern Preview** - Preview a pattern on the frontend with shortcuts in the block editor or from the Patterns post list view.
* **Cross-Site Pattern Copying** - Transfer patterns, including the remote images, between WordPress sites effortlessly. This is useful if you're copying a pattern from one site to another or copying a pattern from a production site to a development site.

> Pattern Wrangler integrates seamlessly with block-based and classic themes offering a hybrid setup with unmatched flexibility.

=== Quick Links ===

Expand All @@ -29,9 +33,9 @@ Pattern Wrangler enhances your experience with WordPress block patterns by addin

=== Requirements and Compatibility ===

Requires WordPress 6.5 or higher.
Requires WordPress 6.5 or higher. 6.7 is recommended.

Compatible with most themes, including block themes.
Fully compatible with most themes, including block themes. Ideal for hybrid setups.

== Installation ==

Expand All @@ -41,9 +45,21 @@ Compatible with most themes, including block themes.

== Frequently Asked Questions ==

= Can Pattern Wrangler import patterns from any WordPress site? =
= Can I import Patterns from any WordPress site? =

Yes! If you have the pattern's code, <a href="https://docs.dlxplugins.com/pattern-wrangler/features/the-pattern-importer-block">Pattern Wrangler can import it</a> and localize any associated images.

= Can I use Patterns in page builders like Elementor? =

Yes! You can use the `[wp_block slug="pattern-slug"]` shortcode <a href="https://docs.dlxplugins.com/pattern-wrangler/features/the-pattern-importer-block">to output block patterns anywhere</a> in your theme or other blocks.

Yes, as long as you have the pattern's code, Pattern Wrangler can import it and localize any images found within.
= Does this work with Block Themes? =

Yes. Although it is designed for hybrid setups, it works with block themes, allowing you to merge theme and plugin-based patterns with your own local patterns stored in your database.

Pattern Wrangler simply makes visible the default `wp_block` post type and category, which is where local patterns are stored.

The Patterns view of this plugin uses the classic Patterns screen, with plans to eventually modernize it and put it on par with the Patterns viewer in the Full-Site Editor.

== Screenshots ==

Expand All @@ -56,6 +72,14 @@ Yes, as long as you have the pattern's code, Pattern Wrangler can import it and

== Changelog ==

= 1.2.0 =
* Released 2024-12-18
* New Feature: Show or hide all unsynced (non-reusable) patterns.
* New Feature: Show or hide all synced (reusable) patterns.
* New Feature: Disable both unsynced and synced patterns to completely disable all local patterns.
* Bug fix: Preview button in the block editor has been fixed for WP 6.7.
* Note: The next major version of Pattern Wrangler (i.e., 1.3.0) will only be compatible with WP 6.7 or higher. The 1.2.x series will involve minor improvements and bug fixes.

= 1.1.2 =
* Released 2024-08-16
* Loading script translations is now working.
Expand Down Expand Up @@ -100,5 +124,5 @@ Yes, as long as you have the pattern's code, Pattern Wrangler can import it and

== Upgrade Notice ==

= 1.1.2 =
Loading script translations is now working.
= 1.2.0 =
New features: Show or hide all synced or unsynced patterns, or disable both to completely disable all local patterns. Bug fix: Preview has been fixed for WP 6.7. Note: To keep up with the pace of WP development, the nex major version (i.e., 1.3.0) will have WP 6.7 and above as a requirement.
77 changes: 33 additions & 44 deletions src/js/blocks/plugins/pattern-preview.js
Original file line number Diff line number Diff line change
@@ -1,57 +1,46 @@
import { useEffect } from 'react';
import { __ } from '@wordpress/i18n';
import { registerPlugin } from '@wordpress/plugins';
import { useSelect } from '@wordpress/data';

// Try to get ActionItem, but don't fail if it's not available
let PluginPreviewMenuItem;
try {
const { PluginPreviewMenuItem: ImportedPluginPreviewMenuItem } = require( '@wordpress/editor' );
PluginPreviewMenuItem = ImportedPluginPreviewMenuItem;
} catch ( e ) {
// ActionItem not available
}

console.log( PluginPreviewMenuItem );

/**
* Render a Preview Button.
*
* @return {Object} The rendered component.
* @return {Object|null} The rendered component or null if ActionItem not available.
*/
const PatternPreviewButton = () => {
useEffect( () => {
const headerToolbar = document.querySelector( '.edit-post-header' );
if ( null === headerToolbar ) {
return;
}

// Get the left toolbar and add to it.
const settingsToolbar = headerToolbar.querySelector( '.edit-post-header__settings' );
if ( null === settingsToolbar ) {
return;
}

// Create the button.
const button = document.createElement( 'a' );
button.className = 'dlx-button-preview components-button has-icon';
button.ariaLabel = __( 'Preview', 'pattern-wrangler' );
button.href = dlxPatternWranglerPreview.previewUrl;
button.target = '_blank';
button.rel = 'noopener noreferrer';

// Add icon.
const icon = document.createElement( 'svg' );
icon.className = 'dlx-pattern-wrangler-preview-icon';
icon.innerHTML = '<svg width="16" height="16" style="display: inline-block; margin-right: 8px;"><use xlink:href="#dlx-pattern-wrangler-preview-icon" /></svg>';
button.prepend( icon );
// Add the button to the toolbar as the first child.
settingsToolbar.prepend( button );
}, [] );
// Return early if ActionItem isn't available
if ( ! PluginPreviewMenuItem ) {
return null;
}

return (
<>
<svg height="0" width="0" xmlns="http://www.w3.org/2000/svg" style={ { display: 'none' } } aria-hidden="true">
<symbol id="dlx-pattern-wrangler-preview-icon"
width="16"
height="16"
viewBox="0 0 512 512"
>
<path fill="currentColor" d="M304 24c0 13.3 10.7 24 24 24h102.1L207 271c-9.4 9.4-9.4 24.6 0 33.9s24.6 9.4 33.9 0l223-223V184c0 13.3 10.7 24 24 24s24-10.7 24-24V24c0-13.3-10.7-24-24-24H328c-13.3 0-24 10.7-24 24zM72 32C32.2 32 0 64.2 0 104v336c0 39.8 32.2 72 72 72h336c39.8 0 72-32.2 72-72V312c0-13.3-10.7-24-24-24s-24 10.7-24 24v128c0 13.3-10.7 24-24 24H72c-13.3 0-24-10.7-24-24V104c0-13.3 10.7-24 24-24h128c13.3 0 24-10.7 24-24s-10.7-24-24-24H72z" />
</symbol>
</svg>
</>
<PluginPreviewMenuItem
icon="external"
label={ __( 'Preview Pattern', 'pattern-wrangler' ) }
onClick={ () => {
window.open( dlxPatternWranglerPreview.previewUrl, '_blank' );
} }
>
{ __( 'Preview Pattern', 'pattern-wrangler' ) }
</PluginPreviewMenuItem>
);
};
registerPlugin( 'dlx-pattern-wrangler-preview-button', {
render: PatternPreviewButton,
} );

// Only register if ActionItem is available
if ( PluginPreviewMenuItem ) {
registerPlugin( 'dlx-pattern-wrangler-preview-button', {
render: PatternPreviewButton,
} );
}

Loading
Loading