social-navigation.php 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112
  1. <?php
  2. // We should only change the render of the navigtion block
  3. // to social links in the following conditions.
  4. function blockbase_condition_to_render_social_menu( $block_content, $block ) {
  5. // The block should be a navigation block.
  6. if ( 'core/navigation' !== $block['blockName'] ) {
  7. return false;
  8. }
  9. // The theme should have a menu defined at the social location.
  10. if ( ! has_nav_menu( 'social' ) ) {
  11. return false;
  12. }
  13. // The block should have an unstable location attribute.
  14. if ( empty( $block['attrs']['__unstableLocation'] ) ) {
  15. return false;
  16. }
  17. // The block should be empty (no custom menu assigned)
  18. if ( ! empty($block['attrs']['navigationMenuId']) || ! empty($block['attrs']['ref']) ) {
  19. return false;
  20. }
  21. // The block should have the class 'social-links'.
  22. if ( empty( $block['attrs']['className'] ) ) {
  23. return false;
  24. }
  25. if ( ! str_contains( $block['attrs']['className'], 'social-links' ) ) {
  26. return false;
  27. }
  28. return true;
  29. }
  30. function blockbase_theme_has_navigation_social_links_settings( $theme_data ) {
  31. return $theme_data
  32. && array_key_exists( 'settings', $theme_data )
  33. && array_key_exists( 'custom', $theme_data['settings'] )
  34. && array_key_exists( 'navigation/social-links', $theme_data['settings']['custom'] )
  35. && array_key_exists( 'color', $theme_data['settings']['custom']['navigation/social-links'] )
  36. && array_key_exists( 'text', $theme_data['settings']['custom']['navigation/social-links']['color'] );
  37. }
  38. function get_social_menu_as_social_links_block( $block ) {
  39. $social_links_location = 'social';
  40. $nav_menu_locations = get_nav_menu_locations();
  41. $social_menu_id = $nav_menu_locations[ $social_links_location ];
  42. $class_name = 'is-style-logos-only';
  43. if ( ! empty( $block['attrs']['itemsJustification'] ) ) {
  44. $class_name .= ' items-justified-' . $block['attrs']['itemsJustification'];
  45. }
  46. // Get color for social icons.
  47. $theme_data = WP_Theme_JSON_Resolver_Gutenberg::get_merged_data()->get_raw_data();
  48. $social_links_icon_color_value = 'var(--wp--custom--color--primary)';
  49. $social_links_icon_color = 'primary';
  50. if ( blockbase_theme_has_navigation_social_links_settings( $theme_data ) ) {
  51. $social_links_icon_color_value = $theme_data['settings']['custom']['navigation/social-links']['color']['text'];
  52. $social_links_icon_color = preg_replace( '/var\(--wp--custom--color--(.+)\)/', '$0 --> $2 $1', $social_links_icon_color_value );
  53. }
  54. $social_links_content = '<!-- wp:social-links {"iconColor":"' . $social_links_icon_color . '","iconColorValue":"' . $social_links_icon_color_value . '","className":"' . $class_name . '"} --><ul class="wp-block-social-links has-icon-color ' . $class_name . '">';
  55. $menu = wp_get_nav_menu_items( $social_menu_id );
  56. if ( $menu ) {
  57. foreach ( $menu as $menu_item ) {
  58. $service_name = preg_replace( '/(-[0-9]+)/', '', $menu_item->post_name );
  59. $service_name = preg_replace( '/(-profile)/', '', $service_name );
  60. $social_links_content .= '<!-- wp:social-link {"url":"' . $menu_item->url . '","service":"' . $service_name . '"} /-->';
  61. }
  62. }
  63. $social_links_content .= '</ul><!-- /wp:social-links -->';
  64. return do_blocks( $social_links_content );
  65. }
  66. function append_social_links_block( $parent_content, $social_links_block ) {
  67. if ( empty( $parent_content ) ) {
  68. return $social_links_block;
  69. }
  70. $dom = new domDocument;
  71. $domXPath = new DomXPath( $dom );
  72. // Since the nav block uses HTML5 element names, we need to suppress the warnings it sends when we loadHTML with HTML5 elements.
  73. libxml_use_internal_errors( true );
  74. $dom->loadHTML( '<?xml encoding="utf-8" ?>' . $parent_content );
  75. $wp_block_navigation__container = $dom->getElementsByTagName( 'ul' )->item( 0 )->parentNode;
  76. $social_links_node = $dom->createDocumentFragment();
  77. $social_links_node->appendXML( $social_links_block );
  78. if ( ! empty( $wp_block_navigation__container ) ) {
  79. $wp_block_navigation__container->appendChild( $social_links_node );
  80. }
  81. $navigation_block = $dom->getElementsByTagName( 'nav' )->item( 0 );
  82. return $dom->saveXML( $navigation_block );
  83. }
  84. function blockbase_social_menu_render( $block_content, $block ) {
  85. if ( blockbase_condition_to_render_social_menu( $block_content, $block ) ) {
  86. $social_links_block = get_social_menu_as_social_links_block( $block );
  87. return append_social_links_block( $block_content, $social_links_block );
  88. }
  89. return $block_content;
  90. }
  91. /**
  92. * Hijack the render of the menu block to inject a social menu.
  93. */
  94. add_filter( 'render_block', 'blockbase_social_menu_render', 10, 2 );