<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head><meta http-equiv="content-type" content="text/html; charset=utf-8" />
<title>[47176] trunk: Block Editor: Include navigation block server logic.</title>
</head>
<body>

<style type="text/css"><!--
#msg dl.meta { border: 1px #006 solid; background: #369; padding: 6px; color: #fff; }
#msg dl.meta dt { float: left; width: 6em; font-weight: bold; }
#msg dt:after { content:':';}
#msg dl, #msg dt, #msg ul, #msg li, #header, #footer, #logmsg { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt;  }
#msg dl a { font-weight: bold}
#msg dl a:link    { color:#fc3; }
#msg dl a:active  { color:#ff0; }
#msg dl a:visited { color:#cc6; }
h3 { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; font-weight: bold; }
#msg pre { white-space: pre-line; overflow: auto; background: #ffc; border: 1px #fa0 solid; padding: 6px; }
#logmsg { background: #ffc; border: 1px #fa0 solid; padding: 1em 1em 0 1em; }
#logmsg p, #logmsg pre, #logmsg blockquote { margin: 0 0 1em 0; }
#logmsg p, #logmsg li, #logmsg dt, #logmsg dd { line-height: 14pt; }
#logmsg h1, #logmsg h2, #logmsg h3, #logmsg h4, #logmsg h5, #logmsg h6 { margin: .5em 0; }
#logmsg h1:first-child, #logmsg h2:first-child, #logmsg h3:first-child, #logmsg h4:first-child, #logmsg h5:first-child, #logmsg h6:first-child { margin-top: 0; }
#logmsg ul, #logmsg ol { padding: 0; list-style-position: inside; margin: 0 0 0 1em; }
#logmsg ul { text-indent: -1em; padding-left: 1em; }#logmsg ol { text-indent: -1.5em; padding-left: 1.5em; }
#logmsg > ul, #logmsg > ol { margin: 0 0 1em 0; }
#logmsg pre { background: #eee; padding: 1em; }
#logmsg blockquote { border: 1px solid #fa0; border-left-width: 10px; padding: 1em 1em 0 1em; background: white;}
#logmsg dl { margin: 0; }
#logmsg dt { font-weight: bold; }
#logmsg dd { margin: 0; padding: 0 0 0.5em 0; }
#logmsg dd:before { content:'\00bb';}
#logmsg table { border-spacing: 0px; border-collapse: collapse; border-top: 4px solid #fa0; border-bottom: 1px solid #fa0; background: #fff; }
#logmsg table th { text-align: left; font-weight: normal; padding: 0.2em 0.5em; border-top: 1px dotted #fa0; }
#logmsg table td { text-align: right; border-top: 1px dotted #fa0; padding: 0.2em 0.5em; }
#logmsg table thead th { text-align: center; border-bottom: 1px solid #fa0; }
#logmsg table th.Corner { text-align: left; }
#logmsg hr { border: none 0; border-top: 2px dashed #fa0; height: 1px; }
#header, #footer { color: #fff; background: #636; border: 1px #300 solid; padding: 6px; }
#patch { width: 100%; }
#patch h4 {font-family: verdana,arial,helvetica,sans-serif;font-size:10pt;padding:8px;background:#369;color:#fff;margin:0;}
#patch .propset h4, #patch .binary h4 {margin:0;}
#patch pre {padding:0;line-height:1.2em;margin:0;}
#patch .diff {width:100%;background:#eee;padding: 0 0 10px 0;overflow:auto;}
#patch .propset .diff, #patch .binary .diff  {padding:10px 0;}
#patch span {display:block;padding:0 10px;}
#patch .modfile, #patch .addfile, #patch .delfile, #patch .propset, #patch .binary, #patch .copfile {border:1px solid #ccc;margin:10px 0;}
#patch ins {background:#dfd;text-decoration:none;display:block;padding:0 10px;}
#patch del {background:#fdd;text-decoration:none;display:block;padding:0 10px;}
#patch .lines, .info {color:#888;background:#fff;}
--></style>
<div id="msg">
<dl class="meta" style="font-size: 105%">
<dt style="float: left; width: 6em; font-weight: bold">Revision</dt> <dd><a style="font-weight: bold" href="https://core.trac.wordpress.org/changeset/47176">47176</a><script type="application/ld+json">{"@context":"http://schema.org","@type":"EmailMessage","description":"Review this Commit","action":{"@type":"ViewAction","url":"https://core.trac.wordpress.org/changeset/47176","name":"Review Commit"}}</script></dd>
<dt style="float: left; width: 6em; font-weight: bold">Author</dt> <dd>jorgefilipecosta</dd>
<dt style="float: left; width: 6em; font-weight: bold">Date</dt> <dd>2020-02-04 20:14:50 +0000 (Tue, 04 Feb 2020)</dd>
</dl>

<pre style='padding-left: 1em; margin: 2em 0; border-left: 2px solid #ccc; line-height: 1.25; font-size: 105%; font-family: sans-serif'>Block Editor: Include navigation block server logic.

Core did not include the navigation block PHP files.
This commit fixes the issue referred, and now the navigation block is executed on the frontend. The block still does not work as expected and throws an error during frontend execution. That problem is going to be fixed on the next WordPress package update.
This commit adds the file as it is on the npm package used.

Props gziolo.
Fixes <a href="https://core.trac.wordpress.org/ticket/49348">#49348</a>.</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunksrcwpsettingsphp">trunk/src/wp-settings.php</a></li>
<li><a href="#trunktestsphpunitincludesfunctionsphp">trunk/tests/phpunit/includes/functions.php</a></li>
<li><a href="#trunktestsphpunittestsrestapirestschemasetupphp">trunk/tests/phpunit/tests/rest-api/rest-schema-setup.php</a></li>
<li><a href="#trunktestsqunitfixtureswpapigeneratedjs">trunk/tests/qunit/fixtures/wp-api-generated.js</a></li>
<li><a href="#trunktoolswebpackpackagesjs">trunk/tools/webpack/packages.js</a></li>
</ul>

<h3>Added Paths</h3>
<ul>
<li><a href="#trunksrcwpincludesblocksnavigationphp">trunk/src/wp-includes/blocks/navigation.php</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunksrcwpincludesblocksnavigationphp"></a>
<div class="addfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Added: trunk/src/wp-includes/blocks/navigation.php</h4>
<pre class="diff"><span>
<span class="info" style="display: block; padding: 0 10px; color: #888">--- trunk/src/wp-includes/blocks/navigation.php                               (rev 0)
+++ trunk/src/wp-includes/blocks/navigation.php 2020-02-04 20:14:50 UTC (rev 47176)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -0,0 +1,195 @@
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+<?php
+/**
+ * Server-side rendering of the `core/navigation` block.
+ *
+ * @package gutenberg
+ */
+
+/**
+ * Build an array with CSS classes and inline styles defining the colors
+ * which will be applied to the navigation markup in the front-end.
+ *
+ * @param  array $attributes Navigation block attributes.
+ * @return array Colors CSS classes and inline styles.
+ */
+function build_css_colors( $attributes ) {
+       // CSS classes.
+       $colors = array(
+               'css_classes'   => array(),
+               'inline_styles' => '',
+       );
+
+       $has_named_text_color  = array_key_exists( 'textColor', $attributes );
+       $has_custom_text_color = array_key_exists( 'customTextColor', $attributes );
+
+       // If has text color.
+       if ( $has_custom_text_color || $has_named_text_color ) {
+               // Add has-text-color class.
+               $colors['css_classes'][] = 'has-text-color';
+       }
+
+       if ( $has_named_text_color ) {
+               // Add the color class.
+               $colors['css_classes'][] = sprintf( 'has-%s-color', $attributes['textColor'] );
+       } elseif ( $has_custom_text_color ) {
+               // Add the custom color inline style.
+               $colors['inline_styles'] = sprintf( 'color: %s;', $attributes['customTextColor'] );
+       }
+
+       return $colors;
+}
+
+/**
+ * Build an array with CSS classes and inline styles defining the font sizes
+ * which will be applied to the navigation markup in the front-end.
+ *
+ * @param  array $attributes Navigation block attributes.
+ * @return array Font size CSS classes and inline styles.
+ */
+function build_css_font_sizes( $attributes ) {
+       // CSS classes.
+       $font_sizes = array(
+               'css_classes'   => array(),
+               'inline_styles' => '',
+       );
+
+       $has_named_font_size  = array_key_exists( 'fontSize', $attributes );
+       $has_custom_font_size = array_key_exists( 'customFontSize', $attributes );
+
+       if ( $has_named_font_size ) {
+               // Add the font size class.
+               $font_sizes['css_classes'][] = sprintf( 'has-%s-font-size', $attributes['fontSize'] );
+       } elseif ( $has_custom_font_size ) {
+               // Add the custom font size inline style.
+               $font_sizes['inline_styles'] = sprintf( 'font-size: %spx;', $attributes['customFontSize'] );
+       }
+
+       return $font_sizes;
+}
+
+/**
+ * Renders the `core/navigation` block on server.
+ *
+ * @param array $attributes The block attributes.
+ * @param array $content The saved content.
+ * @param array $block The parsed block.
+ *
+ * @return string Returns the post content with the legacy widget added.
+ */
+function render_block_navigation( $attributes, $content, $block ) {
+       $colors          = build_css_colors( $attributes );
+       $font_sizes      = build_css_font_sizes( $attributes );
+       $classes         = array_merge(
+               $colors['css_classes'],
+               $font_sizes['css_classes'],
+               array( 'wp-block-navigation' ),
+               isset( $attributes['className'] ) ? array( $attributes['className'] ) : array(),
+               isset( $attributes['itemsJustification'] ) ? array( 'items-justified-' . $attributes['itemsJustification'] ) : array(),
+               isset( $attributes['align'] ) ? array( 'align' . $attributes['align'] ) : array()
+       );
+       $class_attribute = sprintf( ' class="%s"', esc_attr( implode( ' ', $classes ) ) );
+       $style_attribute = ( $colors['inline_styles'] || $font_sizes['inline_styles'] )
+               ? sprintf( ' style="%s"', esc_attr( $colors['inline_styles'] ) . esc_attr( $font_sizes['inline_styles'] ) )
+               : '';
+
+       return sprintf(
+               '<nav %1$s %2$s>%3$s</nav>',
+               $class_attribute,
+               $style_attribute,
+               build_navigation_html( $block, $colors, $font_sizes )
+       );
+}
+
+/**
+ * Walks the inner block structure and returns an HTML list for it.
+ *
+ * @param array $block      The block.
+ * @param array $colors     Contains inline styles and CSS classes to apply to navigation item.
+ * @param array $font_sizes Contains inline styles and CSS classes to apply to navigation item.
+ *
+ * @return string Returns  an HTML list from innerBlocks.
+ */
+function build_navigation_html( $block, $colors, $font_sizes ) {
+       $html            = '';
+       $classes         = array_merge(
+               $colors['css_classes'],
+               $font_sizes['css_classes']
+       );
+       $css_classes     = implode( ' ', $classes );
+       $class_attribute = sprintf( ' class="wp-block-navigation-link__content %s"', esc_attr( trim( $css_classes ) ) );
+       $style_attribute = ( $colors['inline_styles'] || $font_sizes['inline_styles'] )
+               ? sprintf( ' style="%s"', esc_attr( $colors['inline_styles'] ) . esc_attr( $font_sizes['inline_styles'] ) )
+               : '';
+
+       foreach ( (array) $block['innerBlocks'] as $key => $block ) {
+
+               $html .= '<li class="wp-block-navigation-link">' .
+                       '<a' . $class_attribute . $style_attribute;
+
+               // Start appending HTML attributes to anchor tag.
+               if ( isset( $block['attrs']['url'] ) ) {
+                       $html .= ' href="' . esc_url( $block['attrs']['url'] ) . '"';
+               }
+               if ( isset( $block['attrs']['title'] ) ) {
+                       $html .= ' title="' . esc_attr( $block['attrs']['title'] ) . '"';
+               }
+
+               if ( isset( $block['attrs']['opensInNewTab'] ) && true === $block['attrs']['opensInNewTab'] ) {
+                       $html .= ' target="_blank"  ';
+               }
+               // End appending HTML attributes to anchor tag.
+
+               // Start anchor tag content.
+               $html .= '>';
+               if ( isset( $block['attrs']['label'] ) ) {
+                       $html .= esc_html( $block['attrs']['label'] );
+               }
+               $html .= '</a>';
+               // End anchor tag content.
+
+               if ( count( (array) $block['innerBlocks'] ) > 0 ) {
+                       $html .= build_navigation_html( $block, $colors, $font_sizes );
+               }
+
+               $html .= '</li>';
+       }
+       return '<ul>' . $html . '</ul>';
+}
+
+/**
+ * Register the navigation block.
+ *
+ * @uses render_block_navigation()
+ * @throws WP_Error An WP_Error exception parsing the block definition.
+ */
+function register_block_core_navigation() {
+
+       register_block_type(
+               'core/navigation',
+               array(
+                       'attributes'      => array(
+                               'className'          => array(
+                                       'type' => 'string',
+                               ),
+                               'textColor'          => array(
+                                       'type' => 'string',
+                               ),
+                               'customTextColor'    => array(
+                                       'type' => 'string',
+                               ),
+                               'fontSize'           => array(
+                                       'type' => 'string',
+                               ),
+                               'customFontSize'     => array(
+                                       'type' => 'number',
+                               ),
+                               'itemsJustification' => array(
+                                       'type' => 'string',
+                               ),
+                       ),
+
+                       'render_callback' => 'render_block_navigation',
+               )
+       );
+}
+add_action( 'init', 'register_block_core_navigation' );
</ins><span class="cx" style="display: block; padding: 0 10px">Property changes on: trunk/src/wp-includes/blocks/navigation.php
</span><span class="cx" style="display: block; padding: 0 10px">___________________________________________________________________
</span></span></pre></div>
<a id="svneolstyle"></a>
<div class="addfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Added: svn:eol-style</h4></div>
<ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+native
</ins><span class="cx" style="display: block; padding: 0 10px">\ No newline at end of property
</span><a id="trunksrcwpsettingsphp"></a>
<div class="modfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Modified: trunk/src/wp-settings.php</h4>
<pre class="diff"><span>
<span class="info" style="display: block; padding: 0 10px; color: #888">--- trunk/src/wp-settings.php 2020-02-04 19:41:41 UTC (rev 47175)
+++ trunk/src/wp-settings.php   2020-02-04 20:14:50 UTC (rev 47176)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -263,6 +263,7 @@
</span><span class="cx" style="display: block; padding: 0 10px"> require( ABSPATH . WPINC . '/blocks/categories.php' );
</span><span class="cx" style="display: block; padding: 0 10px"> require( ABSPATH . WPINC . '/blocks/latest-comments.php' );
</span><span class="cx" style="display: block; padding: 0 10px"> require( ABSPATH . WPINC . '/blocks/latest-posts.php' );
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+require( ABSPATH . WPINC . '/blocks/navigation.php' );
</ins><span class="cx" style="display: block; padding: 0 10px"> require( ABSPATH . WPINC . '/blocks/rss.php' );
</span><span class="cx" style="display: block; padding: 0 10px"> require( ABSPATH . WPINC . '/blocks/search.php' );
</span><span class="cx" style="display: block; padding: 0 10px"> require( ABSPATH . WPINC . '/blocks/shortcode.php' );
</span></span></pre></div>
<a id="trunktestsphpunitincludesfunctionsphp"></a>
<div class="modfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Modified: trunk/tests/phpunit/includes/functions.php</h4>
<pre class="diff"><span>
<span class="info" style="display: block; padding: 0 10px; color: #888">--- trunk/tests/phpunit/includes/functions.php        2020-02-04 19:41:41 UTC (rev 47175)
+++ trunk/tests/phpunit/includes/functions.php  2020-02-04 20:14:50 UTC (rev 47176)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -301,6 +301,7 @@
</span><span class="cx" style="display: block; padding: 0 10px">        remove_action( 'init', 'register_block_core_categories' );
</span><span class="cx" style="display: block; padding: 0 10px">        remove_action( 'init', 'register_block_core_latest_comments' );
</span><span class="cx" style="display: block; padding: 0 10px">        remove_action( 'init', 'register_block_core_latest_posts' );
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+        remove_action( 'init', 'register_block_core_navigation' );
</ins><span class="cx" style="display: block; padding: 0 10px">         remove_action( 'init', 'register_block_core_rss' );
</span><span class="cx" style="display: block; padding: 0 10px">        remove_action( 'init', 'register_block_core_search' );
</span><span class="cx" style="display: block; padding: 0 10px">        remove_action( 'init', 'register_block_core_shortcode' );
</span></span></pre></div>
<a id="trunktestsphpunittestsrestapirestschemasetupphp"></a>
<div class="modfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Modified: trunk/tests/phpunit/tests/rest-api/rest-schema-setup.php</h4>
<pre class="diff"><span>
<span class="info" style="display: block; padding: 0 10px; color: #888">--- trunk/tests/phpunit/tests/rest-api/rest-schema-setup.php  2020-02-04 19:41:41 UTC (rev 47175)
+++ trunk/tests/phpunit/tests/rest-api/rest-schema-setup.php    2020-02-04 20:14:50 UTC (rev 47176)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -126,6 +126,7 @@
</span><span class="cx" style="display: block; padding: 0 10px">                        '/wp/v2/block-renderer/(?P<name>core/categories)',
</span><span class="cx" style="display: block; padding: 0 10px">                        '/wp/v2/block-renderer/(?P<name>core/latest-comments)',
</span><span class="cx" style="display: block; padding: 0 10px">                        '/wp/v2/block-renderer/(?P<name>core/latest-posts)',
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                        '/wp/v2/block-renderer/(?P<name>core/navigation)',
</ins><span class="cx" style="display: block; padding: 0 10px">                         '/wp/v2/block-renderer/(?P<name>core/rss)',
</span><span class="cx" style="display: block; padding: 0 10px">                        '/wp/v2/block-renderer/(?P<name>core/search)',
</span><span class="cx" style="display: block; padding: 0 10px">                        '/wp/v2/block-renderer/(?P<name>core/shortcode)',
</span></span></pre></div>
<a id="trunktestsqunitfixtureswpapigeneratedjs"></a>
<div class="modfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Modified: trunk/tests/qunit/fixtures/wp-api-generated.js</h4>
<pre class="diff"><span>
<span class="info" style="display: block; padding: 0 10px; color: #888">--- trunk/tests/qunit/fixtures/wp-api-generated.js    2020-02-04 19:41:41 UTC (rev 47175)
+++ trunk/tests/qunit/fixtures/wp-api-generated.js      2020-02-04 20:14:50 UTC (rev 47176)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -4632,6 +4632,46 @@
</span><span class="cx" style="display: block; padding: 0 10px">                 }
</span><span class="cx" style="display: block; padding: 0 10px">             ]
</span><span class="cx" style="display: block; padding: 0 10px">         },
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+        "/wp/v2/block-renderer/(?P<name>core/navigation)": {
+            "namespace": "wp/v2",
+            "methods": [
+                "GET"
+            ],
+            "endpoints": [
+                {
+                    "methods": [
+                        "GET"
+                    ],
+                    "args": {
+                        "name": {
+                            "required": false,
+                            "description": "Unique registered name for the block.",
+                            "type": "string"
+                        },
+                        "context": {
+                            "required": false,
+                            "default": "view",
+                            "enum": [
+                                "edit"
+                            ],
+                            "description": "Scope under which the request is made; determines fields present in response.",
+                            "type": "string"
+                        },
+                        "attributes": {
+                            "required": false,
+                            "default": [],
+                            "description": "Attributes for core/navigation block",
+                            "type": "object"
+                        },
+                        "post_id": {
+                            "required": false,
+                            "description": "ID of the post context.",
+                            "type": "integer"
+                        }
+                    }
+                }
+            ]
+        },
</ins><span class="cx" style="display: block; padding: 0 10px">         "/wp/v2/block-renderer/(?P<name>core/rss)": {
</span><span class="cx" style="display: block; padding: 0 10px">             "namespace": "wp/v2",
</span><span class="cx" style="display: block; padding: 0 10px">             "methods": [
</span></span></pre></div>
<a id="trunktoolswebpackpackagesjs"></a>
<div class="modfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Modified: trunk/tools/webpack/packages.js</h4>
<pre class="diff"><span>
<span class="info" style="display: block; padding: 0 10px; color: #888">--- trunk/tools/webpack/packages.js   2020-02-04 19:41:41 UTC (rev 47175)
+++ trunk/tools/webpack/packages.js     2020-02-04 20:14:50 UTC (rev 47176)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -101,6 +101,7 @@
</span><span class="cx" style="display: block; padding: 0 10px">                'categories',
</span><span class="cx" style="display: block; padding: 0 10px">                'latest-comments',
</span><span class="cx" style="display: block; padding: 0 10px">                'latest-posts',
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                'navigation',
</ins><span class="cx" style="display: block; padding: 0 10px">                 'rss',
</span><span class="cx" style="display: block; padding: 0 10px">                'search',
</span><span class="cx" style="display: block; padding: 0 10px">                'shortcode',
</span></span></pre>
</div>
</div>

</body>
</html>