| 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' ); |