| 1 |
<?php |
| 2 |
/** |
| 3 |
* Plugin Name: NHS Blocks |
| 4 |
* Plugin URI: https://github.com/NHSLeadership/nhsblocks |
| 5 |
* Description: Gutenberg native custom blocks companion plugin for the NHS Nightingale theme (can also be standalone). Based on nhsuk frontend framework. |
| 6 |
* Author: Tony Blacker, NHS Leadership Academy |
| 7 |
* License: GPL v3 |
| 8 |
* Requires at least: 5.0 |
| 9 |
* Tested up to: 6.8.3 |
| 10 |
* |
| 11 |
* Version: 1.4.0 |
| 12 |
* Stable tag: 1.4.0 |
| 13 |
* |
| 14 |
* @package nhsblocks |
| 15 |
*/ |
| 16 |
|
| 17 |
defined( 'ABSPATH' ) || exit; |
| 18 |
|
| 19 |
if (!function_exists('get_plugin_data')) { |
| 20 |
require_once ABSPATH . 'wp-admin/includes/plugin.php'; |
| 21 |
} |
| 22 |
/** |
| 23 |
* Load translations (if any) for the plugin from the /languages/ folder. |
| 24 |
* |
| 25 |
* @link https://developer.wordpress.org/reference/functions/load_plugin_textdomain/ |
| 26 |
*/ |
| 27 |
add_action( 'init', 'nhsblocks_load_textdomain' ); |
| 28 |
|
| 29 |
/** |
| 30 |
* Set the domain to be used for translations. |
| 31 |
*/ |
| 32 |
function nhsblocks_load_textdomain() { |
| 33 |
load_plugin_textdomain( 'nhsblocks', false, basename( __DIR__ ) . '/languages' ); |
| 34 |
} |
| 35 |
|
| 36 |
/** |
| 37 |
* Add custom "nhsblocks" block category. |
| 38 |
* |
| 39 |
* @link https://wordpress.org/gutenberg/handbook/designers-developers/developers/filters/block-filters/#managing-block-categories |
| 40 |
*/ |
| 41 |
add_filter( 'block_categories_all', 'nhsblocks_block_categories', 10, 2 ); |
| 42 |
|
| 43 |
/** |
| 44 |
* Create the category. |
| 45 |
* |
| 46 |
* @param array $categories the details of added categories (in this case an array of 1 item). |
| 47 |
* @param integer $post Unused variable, intended for future expansion of function. |
| 48 |
* |
| 49 |
* @return array |
| 50 |
*/ |
| 51 |
function nhsblocks_block_categories( $categories, $post ) { |
| 52 |
|
| 53 |
return array_merge( |
| 54 |
$categories, |
| 55 |
array( |
| 56 |
array( |
| 57 |
'slug' => 'nhsblocks', |
| 58 |
'title' => __( 'NHS Frontend Blocks', 'nhsblocks' ), |
| 59 |
'icon' => 'screen', |
| 60 |
), |
| 61 |
) |
| 62 |
); |
| 63 |
} |
| 64 |
|
| 65 |
/** |
| 66 |
* Registers all block assets so that they can be enqueued through the Block Editor in |
| 67 |
* the corresponding context. |
| 68 |
* |
| 69 |
* @link https://wordpress.org/gutenberg/handbook/designers-developers/developers/block-api/block-registration/ |
| 70 |
*/ |
| 71 |
add_action( 'init', 'nhsblocks_register_blocks' ); |
| 72 |
|
| 73 |
/** |
| 74 |
* Function to initiate the Gutenberg blocks in this theme. |
| 75 |
*/ |
| 76 |
function nhsblocks_register_blocks() { |
| 77 |
|
| 78 |
// If Block Editor is not active, bail. |
| 79 |
if ( ! function_exists( 'register_block_type' ) ) { |
| 80 |
return; |
| 81 |
} |
| 82 |
|
| 83 |
// Register the block editor script. |
| 84 |
wp_register_script( |
| 85 |
'nhsblocks-editor-script', // label. |
| 86 |
plugins_url( '/build/index.js', __FILE__ ), // script file. |
| 87 |
array( 'wp-blocks', 'wp-i18n', 'wp-element', 'wp-editor', 'wp-data' ), // dependencies. |
| 88 |
'20201202', // version. |
| 89 |
'in_footer' // where to load. |
| 90 |
); |
| 91 |
|
| 92 |
register_block_type( |
| 93 |
'nhsblocks/panel1', |
| 94 |
array( |
| 95 |
'editor_script' => 'nhsblocks-editor-script', |
| 96 |
// Calls registered script above. Registering one brings all. One block to rule them all. |
| 97 |
) |
| 98 |
); |
| 99 |
register_block_type( 'nhsblocks/dashboardnav' ); |
| 100 |
register_block_type( 'nhsblocks/dodont' ); |
| 101 |
register_block_type( 'nhsblocks/nhsbutton' ); |
| 102 |
register_block_type( 'nhsblocks/reveal1' ); |
| 103 |
register_block_type( 'nhsblocks/promo1' ); |
| 104 |
register_block_type( 'nhsblocks/quote1' ); |
| 105 |
register_block_type( 'nhsblocks/card1' ); |
| 106 |
register_block_type( 'nhsblocks/rowgroup' ); |
| 107 |
register_block_type( 'nhsblocks/heroblock' ); |
| 108 |
register_block_type( 'nhsblocks/contentslist' ); |
| 109 |
register_block_type( 'nhsblocks/contentslistitem' ); |
| 110 |
register_block_type( 'nhsblocks/reviewdate' ); |
| 111 |
register_block_type( 'nhsblocks/stripesblock' ); |
| 112 |
|
| 113 |
register_block_type( 'nhsblocks/pagination' ); |
| 114 |
register_block_type( 'nhsblocks/nhstabs' ); |
| 115 |
|
| 116 |
if ( function_exists( 'wp_set_script_translations' ) ) { |
| 117 |
/** |
| 118 |
* Adds internationalization support. |
| 119 |
* |
| 120 |
* @link https://wordpress.org/gutenberg/handbook/designers-developers/developers/internationalization/ |
| 121 |
* @link https://make.wordpress.org/core/2018/11/09/new-javascript-i18n-support-in-wordpress/ |
| 122 |
*/ |
| 123 |
wp_set_script_translations( 'nhsblocks-editor-script', 'nhsblocks', plugins_url( '/languages', __FILE__ ) ); |
| 124 |
} |
| 125 |
|
| 126 |
} |
| 127 |
|
| 128 |
|
| 129 |
add_action( 'plugins_loaded', 'nhsblocks_register_dynamic_blocks' ); |
| 130 |
|
| 131 |
|
| 132 |
/** |
| 133 |
* |
| 134 |
* Taken / Inspired by https://johnblackbourn.com/gutenberg-block-template-part/ |
| 135 |
* |
| 136 |
* Generic block rendering callback function to load a block from a theme template part. |
| 137 |
* |
| 138 |
* Loads a block from the `blocks` subdirectory according to the name of the block, and places the |
| 139 |
* block attributes and block content into namespaced query vars. If there's no corresponding block |
| 140 |
* template part, the block content is returned unaltered. |
| 141 |
* |
| 142 |
* A block named `foo/block1` looks for a template part named `blocks/foo/block1.php`. |
| 143 |
* |
| 144 |
* The block attributes and content can be accessed inside the template part via query vars: |
| 145 |
* |
| 146 |
* - `get_query_var( 'foo/block1/attribute1' )` |
| 147 |
* - `get_query_var( 'foo/block1/attribute2' )` |
| 148 |
* - `get_query_var( 'foo/block1/content' )` |
| 149 |
* |
| 150 |
* @param string $name The full block name, for example 'foo/block1'. |
| 151 |
* @param array $attributes Array of attributes saved on the block instance. |
| 152 |
* @param string $content Optional user-entered block content. Can be null. |
| 153 |
* @return string The dynamic block content. |
| 154 |
*/ |
| 155 |
|
| 156 |
function nhsblocks_register_dynamic_blocks() { |
| 157 |
|
| 158 |
// Only load if Gutenberg is available. |
| 159 |
if ( ! function_exists( 'register_block_type' ) ) { |
| 160 |
return; |
| 161 |
} |
| 162 |
|
| 163 |
$blocks = array( |
| 164 |
'nhsblocks/contentslistpage', |
| 165 |
); |
| 166 |
|
| 167 |
foreach ( $blocks as $block ) { |
| 168 |
|
| 169 |
register_block_type( |
| 170 |
$block, |
| 171 |
[ |
| 172 |
// https://github.com/WordPress/gutenberg/issues/4671. |
| 173 |
'render_callback' => function( array $attributes, string $content = null ) use ( $block ) { |
| 174 |
|
| 175 |
return nhsblocks_block_renderer( $block, $attributes, $content ); |
| 176 |
}, |
| 177 |
] |
| 178 |
); |
| 179 |
|
| 180 |
} |
| 181 |
|
| 182 |
} |
| 183 |
|
| 184 |
/** |
| 185 |
* Undocumented function |
| 186 |
* |
| 187 |
* @param string $name name. |
| 188 |
* @param array $attributes attributes. |
| 189 |
* @param string $content content. |
| 190 |
* @return string |
| 191 |
*/ |
| 192 |
function nhsblocks_block_renderer( string $name, array $attributes, string $content = null ) { |
| 193 |
|
| 194 |
// change template name slash to scores. |
| 195 |
$template_name = str_replace( '/', '-', $name ); |
| 196 |
|
| 197 |
// Set query vars so they are accessible to the template part. |
| 198 |
foreach ( $attributes as $attribute_name => $attribute_value ) { |
| 199 |
set_query_var( $name . '/' . $attribute_name, $attribute_value ); |
| 200 |
} |
| 201 |
set_query_var( $name . '/content', $content ); |
| 202 |
set_query_var( $name . '/class', 'wp-block-' . $template_name ); |
| 203 |
|
| 204 |
// get template file directory |
| 205 |
$template_file = plugin_dir_path( __FILE__ ) . "/templates/{$template_name}.php"; |
| 206 |
|
| 207 |
// Load the template part in an output buffer:. |
| 208 |
ob_start(); |
| 209 |
load_template( $template_file ); |
| 210 |
$output = ob_get_clean(); |
| 211 |
|
| 212 |
// Fall back to just the block content if there's no template part:. |
| 213 |
if ( '' === $output ) { |
| 214 |
$output = (string) $content; |
| 215 |
} |
| 216 |
|
| 217 |
// Clear the query vars so they don't bleed into subsequent instances of the same block type. |
| 218 |
foreach ( $attributes as $attribute_name => $attribute_value ) { |
| 219 |
set_query_var( $name . '/' . $attribute_name, null ); |
| 220 |
} |
| 221 |
set_query_var( $name . '/content', null ); |
| 222 |
|
| 223 |
return $output; |
| 224 |
} |
| 225 |
|
| 226 |
|
| 227 |
/** |
| 228 |
* Build classes based on block attributes. |
| 229 |
* Returns string of classes. |
| 230 |
* |
| 231 |
* @param array $attributes - Block attributes. |
| 232 |
* |
| 233 |
* @return array $classes - the finished array of classes to attach to blocks. |
| 234 |
*/ |
| 235 |
function nhsblocks_block_classes( $attributes ) { |
| 236 |
$classes = null; |
| 237 |
if ( $attributes['align'] ) { |
| 238 |
$classes = 'align' . $attributes['align'] . ' '; |
| 239 |
} |
| 240 |
|
| 241 |
if ( $attributes['className'] ) { |
| 242 |
$classes .= $attributes['className']; |
| 243 |
} |
| 244 |
|
| 245 |
return $classes; |
| 246 |
} |
| 247 |
|
| 248 |
/** |
| 249 |
* Queues up the gutenberg editor style |
| 250 |
*/ |
| 251 |
function nhsblocks_gutenberg_editor_styles() |
| 252 |
{ |
| 253 |
wp_enqueue_style('nhsl-block-editor-styles', plugins_url('style-gutenburg.css', __FILE__), false, '1.1', 'all'); |
| 254 |
$plugin_version = get_bloginfo('version'); // WP version by default. |
| 255 |
$plugin_data = get_plugin_data(plugin_dir_path(__FILE__) . 'nhsblocks.php'); |
| 256 |
if (isset($plugin_data['Name']) && !empty($plugin_data['Version']) && 'NHS Blocks' === $plugin_data['Name']) { |
| 257 |
$plugin_version = $plugin_data['Version']; |
| 258 |
} |
| 259 |
wp_enqueue_style('nhsblocks-editor-styles', plugins_url('style.min.css', __FILE__), false, $plugin_version, 'all'); |
| 260 |
} |
| 261 |
|
| 262 |
add_action( 'enqueue_block_editor_assets', 'nhsblocks_gutenberg_editor_styles' ); // Pulls the enqueued file in to standard wp process. |
| 263 |
|
| 264 |
/** |
| 265 |
* Queues up the blocks styling for front end |
| 266 |
*/ |
| 267 |
function nhsblocks_register_style() { |
| 268 |
$theme = wp_get_theme(); // gets the current theme. |
| 269 |
$parent = wp_get_theme( get_template() ); |
| 270 |
$plugin_version = get_bloginfo( 'version' ); // WP version by default. |
| 271 |
if ( 'Nightingale' !== $theme->name && ( 'Nightingale' !== $parent->name ) ) { |
| 272 |
$plugin_data = get_plugin_data( plugin_dir_path( __FILE__ ) . 'nhsblocks.php' ); |
| 273 |
if ( isset( $plugin_data['Name'] ) && ! empty( $plugin_data['Version'] ) && 'NHS Blocks' === $plugin_data['Name'] ) { |
| 274 |
$plugin_version = $plugin_data['Version']; |
| 275 |
} |
| 276 |
wp_register_style( 'nhsblocks', plugins_url( 'style.min.css', __FILE__ ), array(), $plugin_version, 'all' ); |
| 277 |
} |
| 278 |
} |
| 279 |
|
| 280 |
add_action( 'init', 'nhsblocks_register_style' ); // Pulls front end styling to standard wp process. |
| 281 |
|
| 282 |
/** |
| 283 |
* Nhsblocks enqueue style. |
| 284 |
* |
| 285 |
* @return void |
| 286 |
*/ |
| 287 |
function nhsblocks_enqueue_style() { |
| 288 |
$theme = wp_get_theme(); // gets the current theme. |
| 289 |
if ( 'Nightingale' !== $theme->name ) { |
| 290 |
wp_enqueue_style( 'nhsblocks' ); |
| 291 |
|
| 292 |
wp_enqueue_script( |
| 293 |
'nhsblocks-frontend', |
| 294 |
plugins_url( 'build/nhsblocks-frontend.min.js', __FILE__ ), |
| 295 |
array(), |
| 296 |
filemtime( plugin_dir_path( __FILE__ ) . 'build/nhsblocks-frontend.min.js' ), |
| 297 |
true |
| 298 |
); |
| 299 |
|
| 300 |
} |
| 301 |
} |
| 302 |
|
| 303 |
add_action( 'wp_enqueue_scripts', 'nhsblocks_enqueue_style' ); |
| 304 |
|
| 305 |
/** |
| 306 |
* Hero footer |
| 307 |
* |
| 308 |
* @return void |
| 309 |
*/ |
| 310 |
function nhsblocks_hero_footer() { |
| 311 |
$theme = wp_get_theme(); // gets the current theme. |
| 312 |
$scriptout = "<script> |
| 313 |
|
| 314 |
const heroBlock = document.querySelector('.wp-block-nhsblocks-heroblock'); |
| 315 |
const tabbedTabs = document.querySelector( '.nhsuk-bordered-tabs-container' ); |
| 316 |
if ( ( heroBlock ) ) { |
| 317 |
matches = heroBlock.matches ? heroBlock.matches('.wp-block-nhsblocks-heroblock') : heroBlock.msMatchesSelector('.wp-block-nhsblocks-heroblock'); |
| 318 |
if ( matches === true ) { "; |
| 319 |
if ( 'Nightingale' === $theme->name || 'Nightingale' === $theme->parent_theme ) { |
| 320 |
$scriptout .= " |
| 321 |
const mainContent = document.querySelector( 'main' ); |
| 322 |
const contentInner = document.querySelector( '#contentinner' ); |
| 323 |
const wholeDoc = document.querySelector( 'body' ); |
| 324 |
const breadCrumb = document.querySelector( '.nhsuk-breadcrumb' ); |
| 325 |
const articleTitle = document.querySelector( '.entry-header' ); |
| 326 |
const sectionTitle = wholeDoc.querySelector( '#nhsuk-tabbed-title' ); |
| 327 |
const tabbedTabs = document.querySelector( '.nhsuk-bordered-tabs-container' );"; |
| 328 |
} else { |
| 329 |
$scriptout .= " |
| 330 |
const mainContent = document.querySelector( 'main' ); |
| 331 |
const contentInner = document.querySelector( 'article' ); |
| 332 |
const wholeDoc = document.querySelector( 'body' ); |
| 333 |
const articleTitle = document.querySelector( '.entry-header' );"; |
| 334 |
} |
| 335 |
$scriptout .= " |
| 336 |
mainContent.insertBefore( heroBlock, contentInner ); |
| 337 |
articleTitle.style.display = 'none'; |
| 338 |
mainContent.style.paddingTop = '0'; |
| 339 |
if ( tabbedTabs ) { |
| 340 |
mainContent.insertBefore( tabbedTabs, contentInner ); |
| 341 |
heroBlock.style.borderBottom = '70px solid white'; |
| 342 |
heroBlock.style.marginBottom = 'none'; |
| 343 |
} else { |
| 344 |
heroBlock.style.marginBottom = '70px'; |
| 345 |
} |
| 346 |
if ( breadCrumb ) { |
| 347 |
wholeDoc.removeChild( breadCrumb ); |
| 348 |
} |
| 349 |
if ( sectionTitle ) { |
| 350 |
removeElements( document.querySelectorAll('#nhsuk-tabbed-title') ); |
| 351 |
} |
| 352 |
} |
| 353 |
} else if ( tabbedTabs ) {"; |
| 354 |
if ( 'Nightingale' === $theme->name || 'Nightingale' === $theme->parent_theme ) { |
| 355 |
$scriptout .= " |
| 356 |
const mainContent = document.querySelector( 'main' ); |
| 357 |
const contentInner = document.querySelector( '#contentinner' ); |
| 358 |
const wholeDoc = document.querySelector( 'body' ); |
| 359 |
const breadCrumb = document.querySelector( '.nhsuk-breadcrumb' ); |
| 360 |
const articleTitle = document.querySelector( '.entry-header' ); |
| 361 |
const sectionTitle = wholeDoc.querySelector( '#nhsuk-tabbed-title' );"; |
| 362 |
|
| 363 |
} else { |
| 364 |
$scriptout .= " |
| 365 |
const mainContent = document.querySelector( 'main' ); |
| 366 |
const contentInner = document.querySelector( 'article' ); |
| 367 |
const wholeDoc = document.querySelector( 'body' ); |
| 368 |
const articleTitle = document.querySelector( '.entry-header' );"; |
| 369 |
} |
| 370 |
|
| 371 |
$scriptout .= " |
| 372 |
mainContent.insertBefore( tabbedTabs, contentInner ); |
| 373 |
if ( breadCrumb ) { |
| 374 |
wholeDoc.removeChild( breadCrumb ); |
| 375 |
} |
| 376 |
if ( sectionTitle ) { |
| 377 |
removeElements( document.querySelectorAll( '#nhsuk-tabbed-title' ) ); |
| 378 |
} |
| 379 |
articleTitle.style.marginTop = '20px'; |
| 380 |
mainContent.style.paddingTop = '0'; |
| 381 |
} |
| 382 |
// Page Link JS |
| 383 |
const careCardWarning = document.querySelector('.nhsuk-care-card.is-style-warning-callout'); |
| 384 |
if ( ( careCardWarning ) ) { |
| 385 |
const visuallyHidden = careCardWarning.querySelector('.nhsuk-u-visually-hidden'); |
| 386 |
jQuery(visuallyHidden).html('Warning advice: '); |
| 387 |
} |
| 388 |
const careCardUrgent = document.querySelector('.nhsuk-care-card.is-style-urgent'); |
| 389 |
if ( ( careCardUrgent ) ) { |
| 390 |
const visuallyHidden = careCardUrgent.querySelector('.nhsuk-u-visually-hidden'); |
| 391 |
jQuery(visuallyHidden).html('Urgent advice: '); |
| 392 |
} |
| 393 |
const careCardImmediate = document.querySelector('.nhsuk-care-card.is-style-immediate'); |
| 394 |
if ( ( careCardImmediate ) ) { |
| 395 |
const visuallyHidden = careCardImmediate.querySelector('.nhsuk-u-visually-hidden'); |
| 396 |
jQuery(visuallyHidden).html('Immediate action required: '); |
| 397 |
} |
| 398 |
|
| 399 |
( function(){ |
| 400 |
let url = window.location.href.split(/[?#]/)[0]; |
| 401 |
let pageList = document.querySelectorAll('.nhsuk-contents-list li.nhsuk-contents-list__item'); |
| 402 |
for (var i = pageList.length - 1; i >= 0; i--) { |
| 403 |
let nhsList = pageList[i]; |
| 404 |
let link = pageList[i].children[0].href; |
| 405 |
if( link === url ){ |
| 406 |
let txt = pageList[i].innerText; |
| 407 |
pageList[i].innerHTML = txt; |
| 408 |
} |
| 409 |
} |
| 410 |
})(); |
| 411 |
// Smooth scroll to link |
| 412 |
jQuery( document ).ready(function( $ ) { |
| 413 |
$('.js-scroll-to').on('click', function(e) { |
| 414 |
e.preventDefault(); |
| 415 |
let link = $(this).attr('href'); |
| 416 |
$('html, body').animate({ |
| 417 |
scrollTop: $( link ).offset().top - 50 |
| 418 |
}, 200); |
| 419 |
}); |
| 420 |
}); |
| 421 |
</script>"; |
| 422 |
echo $scriptout; |
| 423 |
} |
| 424 |
|
| 425 |
add_action( 'wp_footer', 'nhsblocks_hero_footer' ); |
| 426 |
|