| | 1 | <?php |
| | 2 | /** |
| | 3 | * Server-side rendering of the `core/navigation` block. |
| | 4 | * |
| | 5 | * @package gutenberg |
| | 6 | */ |
| | 7 | |
| | 8 | /** |
| | 9 | * Build an array with CSS classes and inline styles defining the colors |
| | 10 | * which will be applied to the navigation markup in the front-end. |
| | 11 | * |
| | 12 | * @param array $attributes Navigation block attributes. |
| | 13 | * @return array Colors CSS classes and inline styles. |
| | 14 | */ |
| | 15 | function build_css_colors( $attributes ) { |
| | 16 | // CSS classes. |
| | 17 | $colors = array( |
| | 18 | 'css_classes' => array(), |
| | 19 | 'inline_styles' => '', |
| | 20 | ); |
| | 21 | |
| | 22 | $has_named_text_color = array_key_exists( 'textColor', $attributes ); |
| | 23 | $has_custom_text_color = array_key_exists( 'customTextColor', $attributes ); |
| | 24 | |
| | 25 | // If has text color. |
| | 26 | if ( $has_custom_text_color || $has_named_text_color ) { |
| | 27 | // Add has-text-color class. |
| | 28 | $colors['css_classes'][] = 'has-text-color'; |
| | 29 | } |
| | 30 | |
| | 31 | if ( $has_named_text_color ) { |
| | 32 | // Add the color class. |
| | 33 | $colors['css_classes'][] = sprintf( 'has-%s-color', $attributes['textColor'] ); |
| | 34 | } elseif ( $has_custom_text_color ) { |
| | 35 | // Add the custom color inline style. |
| | 36 | $colors['inline_styles'] = sprintf( 'color: %s;', $attributes['customTextColor'] ); |
| | 37 | } |
| | 38 | |
| | 39 | return $colors; |
| | 40 | } |
| | 41 | |
| | 42 | /** |
| | 43 | * Build an array with CSS classes and inline styles defining the font sizes |
| | 44 | * which will be applied to the navigation markup in the front-end. |
| | 45 | * |
| | 46 | * @param array $attributes Navigation block attributes. |
| | 47 | * @return array Font size CSS classes and inline styles. |
| | 48 | */ |
| | 49 | function build_css_font_sizes( $attributes ) { |
| | 50 | // CSS classes. |
| | 51 | $font_sizes = array( |
| | 52 | 'css_classes' => array(), |
| | 53 | 'inline_styles' => '', |
| | 54 | ); |
| | 55 | |
| | 56 | $has_named_font_size = array_key_exists( 'fontSize', $attributes ); |
| | 57 | $has_custom_font_size = array_key_exists( 'customFontSize', $attributes ); |
| | 58 | |
| | 59 | if ( $has_named_font_size ) { |
| | 60 | // Add the font size class. |
| | 61 | $font_sizes['css_classes'][] = sprintf( 'has-%s-font-size', $attributes['fontSize'] ); |
| | 62 | } elseif ( $has_custom_font_size ) { |
| | 63 | // Add the custom font size inline style. |
| | 64 | $font_sizes['inline_styles'] = sprintf( 'font-size: %spx;', $attributes['customFontSize'] ); |
| | 65 | } |
| | 66 | |
| | 67 | return $font_sizes; |
| | 68 | } |
| | 69 | |
| | 70 | /** |
| | 71 | * Renders the `core/navigation` block on server. |
| | 72 | * |
| | 73 | * @param array $attributes The block attributes. |
| | 74 | * @param array $content The saved content. |
| | 75 | * @param array $block The parsed block. |
| | 76 | * |
| | 77 | * @return string Returns the post content with the legacy widget added. |
| | 78 | */ |
| | 79 | function render_block_navigation( $attributes, $content, $block ) { |
| | 80 | $colors = build_css_colors( $attributes ); |
| | 81 | $font_sizes = build_css_font_sizes( $attributes ); |
| | 82 | $classes = array_merge( |
| | 83 | $colors['css_classes'], |
| | 84 | $font_sizes['css_classes'], |
| | 85 | array( 'wp-block-navigation' ), |
| | 86 | isset( $attributes['className'] ) ? array( $attributes['className'] ) : array(), |
| | 87 | isset( $attributes['itemsJustification'] ) ? array( 'items-justified-' . $attributes['itemsJustification'] ) : array(), |
| | 88 | isset( $attributes['align'] ) ? array( 'align' . $attributes['align'] ) : array() |
| | 89 | ); |
| | 90 | $class_attribute = sprintf( ' class="%s"', esc_attr( implode( ' ', $classes ) ) ); |
| | 91 | $style_attribute = ( $colors['inline_styles'] || $font_sizes['inline_styles'] ) |
| | 92 | ? sprintf( ' style="%s"', esc_attr( $colors['inline_styles'] ) . esc_attr( $font_sizes['inline_styles'] ) ) |
| | 93 | : ''; |
| | 94 | |
| | 95 | return sprintf( |
| | 96 | '<nav %1$s %2$s>%3$s</nav>', |
| | 97 | $class_attribute, |
| | 98 | $style_attribute, |
| | 99 | build_navigation_html( $block, $colors, $font_sizes ) |
| | 100 | ); |
| | 101 | } |
| | 102 | |
| | 103 | /** |
| | 104 | * Walks the inner block structure and returns an HTML list for it. |
| | 105 | * |
| | 106 | * @param array $block The block. |
| | 107 | * @param array $colors Contains inline styles and CSS classes to apply to navigation item. |
| | 108 | * @param array $font_sizes Contains inline styles and CSS classes to apply to navigation item. |
| | 109 | * |
| | 110 | * @return string Returns an HTML list from innerBlocks. |
| | 111 | */ |
| | 112 | function build_navigation_html( $block, $colors, $font_sizes ) { |
| | 113 | $html = ''; |
| | 114 | $classes = array_merge( |
| | 115 | $colors['css_classes'], |
| | 116 | $font_sizes['css_classes'] |
| | 117 | ); |
| | 118 | $css_classes = implode( ' ', $classes ); |
| | 119 | $class_attribute = sprintf( ' class="wp-block-navigation-link__content %s"', esc_attr( trim( $css_classes ) ) ); |
| | 120 | $style_attribute = ( $colors['inline_styles'] || $font_sizes['inline_styles'] ) |
| | 121 | ? sprintf( ' style="%s"', esc_attr( $colors['inline_styles'] ) . esc_attr( $font_sizes['inline_styles'] ) ) |
| | 122 | : ''; |
| | 123 | |
| | 124 | foreach ( (array) $block['innerBlocks'] as $key => $block ) { |
| | 125 | |
| | 126 | $html .= '<li class="wp-block-navigation-link">' . |
| | 127 | '<a' . $class_attribute . $style_attribute; |
| | 128 | |
| | 129 | // Start appending HTML attributes to anchor tag. |
| | 130 | if ( isset( $block['attrs']['url'] ) ) { |
| | 131 | $html .= ' href="' . esc_url( $block['attrs']['url'] ) . '"'; |
| | 132 | } |
| | 133 | if ( isset( $block['attrs']['title'] ) ) { |
| | 134 | $html .= ' title="' . esc_attr( $block['attrs']['title'] ) . '"'; |
| | 135 | } |
| | 136 | |
| | 137 | if ( isset( $block['attrs']['opensInNewTab'] ) && true === $block['attrs']['opensInNewTab'] ) { |
| | 138 | $html .= ' target="_blank" '; |
| | 139 | } |
| | 140 | // End appending HTML attributes to anchor tag. |
| | 141 | |
| | 142 | // Start anchor tag content. |
| | 143 | $html .= '>'; |
| | 144 | if ( isset( $block['attrs']['label'] ) ) { |
| | 145 | $html .= esc_html( $block['attrs']['label'] ); |
| | 146 | } |
| | 147 | $html .= '</a>'; |
| | 148 | // End anchor tag content. |
| | 149 | |
| | 150 | if ( count( (array) $block['innerBlocks'] ) > 0 ) { |
| | 151 | $html .= build_navigation_html( $block, $colors, $font_sizes ); |
| | 152 | } |
| | 153 | |
| | 154 | $html .= '</li>'; |
| | 155 | } |
| | 156 | return '<ul>' . $html . '</ul>'; |
| | 157 | } |
| | 158 | |
| | 159 | /** |
| | 160 | * Register the navigation block. |
| | 161 | * |
| | 162 | * @uses render_block_navigation() |
| | 163 | * @throws WP_Error An WP_Error exception parsing the block definition. |
| | 164 | */ |
| | 165 | function register_block_core_navigation() { |
| | 166 | |
| | 167 | register_block_type( |
| | 168 | 'core/navigation', |
| | 169 | array( |
| | 170 | 'attributes' => array( |
| | 171 | 'className' => array( |
| | 172 | 'type' => 'string', |
| | 173 | ), |
| | 174 | 'textColor' => array( |
| | 175 | 'type' => 'string', |
| | 176 | ), |
| | 177 | 'customTextColor' => array( |
| | 178 | 'type' => 'string', |
| | 179 | ), |
| | 180 | 'fontSize' => array( |
| | 181 | 'type' => 'string', |
| | 182 | ), |
| | 183 | 'customFontSize' => array( |
| | 184 | 'type' => 'number', |
| | 185 | ), |
| | 186 | 'itemsJustification' => array( |
| | 187 | 'type' => 'string', |
| | 188 | ), |
| | 189 | ), |
| | 190 | |
| | 191 | 'render_callback' => 'render_block_navigation', |
| | 192 | ) |
| | 193 | ); |
| | 194 | } |
| | 195 | add_action( 'init', 'register_block_core_navigation' ); |