forked from getdave/responsive-navigation-block
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathgetdave-responsive-navigation-block.php
More file actions
303 lines (258 loc) · 10.1 KB
/
getdave-responsive-navigation-block.php
File metadata and controls
303 lines (258 loc) · 10.1 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
<?php
/**
* Plugin Name: Responsive Navigation Block
* Description: Allows you to show different navigation menus based on the screen size using the Navigation block.
* Requires at least: 6.5
* Version: 1.0.9
* Author: Dave Smith
* Author URI: https://aheadcreative.co.uk
* Plugin URI: https://github.com/getdave/responsive-navigation-block
* License: GPL-2.0-or-later
* License URI: https://www.gnu.org/licenses/old-licenses/gpl-2.0.html
* Text Domain: getdave-responsive-navigation-block
*
* @package getdave
*/
namespace GETDAVERNB;
// If this file is called directly, abort.
if ( ! defined( 'WPINC' ) ) {
die;
}
/**
* Constants.
*/
define( 'GDRNB_PLUGIN_SLUG', 'getdave-responsive-navigation-block' );
define( 'GDRNB_PLUGIN_SLUG_SHORT', 'getdavernb' );
define( 'GDRNB_DEFAULT_BREAKPOINT', 782 );
define( 'GDRNB_DEFAULT_UNIT', 'px' );
define( 'GDRNB_MOBILE_NAV_CLASS', GDRNB_PLUGIN_SLUG . '-is-mobile' );
define( 'GDRNB_DESKTOP_NAV_CLASS', GDRNB_PLUGIN_SLUG . '-is-desktop' );
/**
* Initialize the plugin.
*/
function init() {
add_action( 'init', __NAMESPACE__ . '\register_assets' );
add_action( 'enqueue_block_editor_assets', __NAMESPACE__ . '\enqueue_block_editor_assets' );
add_action( 'enqueue_block_assets', __NAMESPACE__ . '\enqueue_block_assets' );
add_action( 'admin_init', __NAMESPACE__ . '\register_settings' );
add_action( 'admin_menu', __NAMESPACE__ . '\add_settings_page' );
add_filter( 'default_wp_template_part_areas', __NAMESPACE__ . '\template_part_areas' );
add_filter( 'render_block_core/navigation', __NAMESPACE__ . '\display_template_part', 10, 2 );
}
function uninstall_plugin() {
delete_option( GDRNB_PLUGIN_SLUG . '_responsive_nav_breakpoint' );
delete_option( GDRNB_PLUGIN_SLUG . '_responsive_nav_unit' );
}
/**
* Register the assets.
*/
function register_assets() {
$asset_file = plugin_dir_path( __FILE__ ) . '/build/index.asset.php';
if ( file_exists( $asset_file ) ) {
$assets = include $asset_file;
wp_register_script(
'getdavernb-script',
plugins_url( 'build/index.js', __FILE__ ),
$assets['dependencies'],
$assets['version'],
true
);
}
}
/**
* Enqueue the editor assets.
*/
function enqueue_block_editor_assets() {
wp_enqueue_script(
'getdavernb-script',
);
// Inline variables for access in JavaScript.
$inline_variables = array(
'classNames' => array(
'mobile' => GDRNB_MOBILE_NAV_CLASS,
'desktop' => GDRNB_DESKTOP_NAV_CLASS,
),
'pluginName' => GDRNB_PLUGIN_SLUG,
);
wp_add_inline_script(
'getdavernb-script',
'const ' . strtoupper( GDRNB_PLUGIN_SLUG_SHORT ) . ' = ' . wp_json_encode( $inline_variables ) . ';',
'before'
);
}
/**
* Dynamically generate the CSS for the block breakpoints
* using the defined breakpoint.
*
* @return string
*/
function generate_block_breakpoints_css( $breakpoint, $unit ) {
// "Late" sanitization for the breakpoint and unit.
// These are pre-validated in the settings page `sanitize_callback`
// but we'll sanitize them here to ensure they're safe to use in CSS.
$breakpoint = absint( $breakpoint );
$unit = sanitize_text_field( $unit );
return '
@media (min-width: ' . esc_attr( $breakpoint ) . esc_attr( $unit ) . ') {
.wp-block-navigation.' . esc_attr( GDRNB_MOBILE_NAV_CLASS ) . ' {
display: none;
}
}
@media (max-width: calc(' . esc_attr( $breakpoint ) . esc_attr( $unit ) . ' - 1px)) {
.wp-block-navigation.' . esc_attr( GDRNB_DESKTOP_NAV_CLASS ) . ' {
display: none;
}
}
';
}
function enqueue_block_assets() {
$breakpoint = get_option( GDRNB_PLUGIN_SLUG . '_responsive_nav_breakpoint', GDRNB_DEFAULT_BREAKPOINT );
$unit = get_option( GDRNB_PLUGIN_SLUG . '_responsive_nav_unit', GDRNB_DEFAULT_UNIT );
$css = generate_block_breakpoints_css( $breakpoint, $unit );
// Create a fake stylesheet to allow for inlining the CSS rules.
wp_register_style( GDRNB_PLUGIN_SLUG . '-style', false );
wp_enqueue_style( GDRNB_PLUGIN_SLUG . '-style' );
wp_add_inline_style( GDRNB_PLUGIN_SLUG . '-style', $css );
}
function add_settings_page() {
add_options_page(
__( 'Responsive Navigation Block Settings', 'getdave-responsive-navigation-block' ), // Page title
__( 'Responsive Navigation Block', 'getdave-responsive-navigation-block' ), // Menu title
'manage_options', // Capability
GDRNB_PLUGIN_SLUG . '_responsive_nav', // Menu slug
__NAMESPACE__ . '\settings_page_callback' // Callback function
);
}
function settings_page_callback() {
?>
<div class="wrap">
<h1><?php echo esc_html( get_admin_page_title() ); ?></h1>
<form action="options.php" method="post">
<?php
settings_fields( GDRNB_PLUGIN_SLUG . '_responsive_nav' ); // Use your custom settings group
do_settings_sections( GDRNB_PLUGIN_SLUG . '_responsive_nav' );
submit_button( __( 'Save Settings', 'getdave-responsive-navigation-block' ) );
?>
</form>
</div>
<?php
}
function register_settings() {
register_setting(
GDRNB_PLUGIN_SLUG . '_responsive_nav', // Custom settings group
GDRNB_PLUGIN_SLUG . '_responsive_nav_breakpoint',
array(
'type' => 'integer',
'description' => __( 'The breakpoint value at which the navigation will switch.', 'getdave-responsive-navigation-block' ),
'sanitize_callback' => 'absint',
'default' => GDRNB_DEFAULT_BREAKPOINT,
)
);
register_setting(
GDRNB_PLUGIN_SLUG . '_responsive_nav', // Custom settings group
GDRNB_PLUGIN_SLUG . '_responsive_nav_unit',
array(
'type' => 'string',
'description' => __( 'The unit used for the breakpoint.', 'getdave-responsive-navigation-block' ),
'sanitize_callback' => 'sanitize_text_field',
'default' => GDRNB_DEFAULT_UNIT,
)
);
add_settings_section(
GDRNB_PLUGIN_SLUG . '_responsive_nav_settings_section',
__( 'Responsive Navigation Settings', 'getdave-responsive-navigation-block' ),
__NAMESPACE__ . '\settings_section_callback',
GDRNB_PLUGIN_SLUG . '_responsive_nav'
);
add_settings_field(
GDRNB_PLUGIN_SLUG . '_responsive_nav_breakpoint',
__( 'Breakpoint', 'getdave-responsive-navigation-block' ),
__NAMESPACE__ . '\settings_field_callback',
GDRNB_PLUGIN_SLUG . '_responsive_nav',
GDRNB_PLUGIN_SLUG . '_responsive_nav_settings_section'
);
add_settings_field(
GDRNB_PLUGIN_SLUG . '_responsive_nav_unit',
__( 'Breakpoint Unit', 'getdave-responsive-navigation-block' ),
__NAMESPACE__ . '\settings_field_unit_callback',
GDRNB_PLUGIN_SLUG . '_responsive_nav',
GDRNB_PLUGIN_SLUG . '_responsive_nav_settings_section'
);
}
function settings_section_callback() {
echo '<p>' . esc_html__( 'Set the breakpoint and unit at which the special Navigation block variations "Desktop Navigation" and "Mobile Navigation" will switch.', 'getdave-responsive-navigation-block' ) . '</p>';
echo '<p>' . esc_html__( '⚠️ Please note: setting this value will have no effect on the standard Navigation block.', 'getdave-responsive-navigation-block' ) . '</p>';
}
function settings_field_callback() {
$breakpoint = get_option( GDRNB_PLUGIN_SLUG . '_responsive_nav_breakpoint', GDRNB_DEFAULT_BREAKPOINT );
echo '<input type="number" name="' . esc_attr( GDRNB_PLUGIN_SLUG ) . '_responsive_nav_breakpoint" value="' . esc_attr( $breakpoint ) . '" min="0">';
}
function settings_field_unit_callback() {
$unit = get_option( GDRNB_PLUGIN_SLUG . '_responsive_nav_unit', GDRNB_DEFAULT_UNIT );
?>
<select id="<?php echo esc_attr( GDRNB_PLUGIN_SLUG . '_responsive_nav_unit' ); ?>" name="<?php echo esc_attr( GDRNB_PLUGIN_SLUG . '_responsive_nav_unit' ); ?>">
<option value="px" <?php selected( $unit, 'px' ); ?>>px</option>
<option value="em" <?php selected( $unit, 'em' ); ?>>em</option>
<option value="rem" <?php selected( $unit, 'rem' ); ?>>rem</option>
<option value="vw" <?php selected( $unit, 'vw' ); ?>>vw</option>
</select>
<?php
}
/**
* Adds a custom template part area for mega menus to the list of template part areas.
*
* This function introduces a new area specifically for menu templates.
* The new area is appended to the existing list of template part areas.
*
* @see https://developer.wordpress.org/reference/hooks/default_wp_template_part_areas/
*
* @param array $areas Existing array of template part areas.
* @return array Modified array of template part areas including the new mega menu area.
*/
function template_part_areas( array $areas ) {
$areas[] = array(
'area' => 'menu',
'area_tag' => 'div',
'description' => __( 'Menu templates are used for more complex layouts.', 'getdave-responsive-navigation-block' ),
'icon' => 'layout',
'label' => __( 'Menu', 'getdave-responsive-navigation-block' ),
);
return $areas;
}
// Include the Simple HTML DOM parser
require __DIR__ . '/vendor/autoload.php';
use voku\helper\HtmlDomParser;
function replaceDivContentWithSimpleHTMLDOM($html, $newContent) {
// Load the HTML string into the Simple HTML DOM object
$htmlDoc = HtmlDomParser::str_get_html($html);
// Find the div with the class wp-block-navigation__responsive-container-content
$div = $htmlDoc->find('div.wp-block-navigation__responsive-container-content', 0);
// If the div is found, replace its inner content
if ($div) {
$div->innertext = $newContent;
}
// Return the updated HTML
return $htmlDoc->save();
}
function display_template_part( $block_content, $block ) {
if ( $block['blockName'] === 'core/navigation' ) {
if(
array_key_exists( 'className', $block['attrs'] )
&& str_contains( $block['attrs']['className'], GDRNB_MOBILE_NAV_CLASS )
&& array_key_exists( 'overlayMenu', $block['attrs'] )
&& $block['attrs']['overlayMenu'] === 'always'
&& array_key_exists( 'menuSlug', $block['attrs'] )
&& ! empty( $block['attrs']['menuSlug'] )
) {
ob_start();
block_template_part( $block['attrs']['menuSlug'] );
$template_markup = ob_get_clean();
return replaceDivContentWithSimpleHTMLDOM( $block_content, $template_markup );
}
}
return $block_content;
}
// Handle uninstallation.
register_uninstall_hook( __FILE__, 'uninstall_plugin' );
// Handle initialization.
init();