aboutsummaryrefslogtreecommitdiff
path: root/srcs/wordpress/wp-includes/blocks
diff options
context:
space:
mode:
Diffstat (limited to 'srcs/wordpress/wp-includes/blocks')
-rw-r--r--srcs/wordpress/wp-includes/blocks/archives.php143
-rw-r--r--srcs/wordpress/wp-includes/blocks/block.php48
-rw-r--r--srcs/wordpress/wp-includes/blocks/calendar.php78
-rw-r--r--srcs/wordpress/wp-includes/blocks/categories.php120
-rw-r--r--srcs/wordpress/wp-includes/blocks/latest-comments.php196
-rw-r--r--srcs/wordpress/wp-includes/blocks/latest-posts.php177
-rw-r--r--srcs/wordpress/wp-includes/blocks/rss.php160
-rw-r--r--srcs/wordpress/wp-includes/blocks/search.php93
-rw-r--r--srcs/wordpress/wp-includes/blocks/shortcode.php37
-rw-r--r--srcs/wordpress/wp-includes/blocks/tag-cloud.php78
10 files changed, 1130 insertions, 0 deletions
diff --git a/srcs/wordpress/wp-includes/blocks/archives.php b/srcs/wordpress/wp-includes/blocks/archives.php
new file mode 100644
index 0000000..172b1c7
--- /dev/null
+++ b/srcs/wordpress/wp-includes/blocks/archives.php
@@ -0,0 +1,143 @@
+<?php
+/**
+ * Server-side rendering of the `core/archives` block.
+ *
+ * @package WordPress
+ */
+
+/**
+ * Renders the `core/archives` block on server.
+ *
+ * @see WP_Widget_Archives
+ *
+ * @param array $attributes The block attributes.
+ *
+ * @return string Returns the post content with archives added.
+ */
+function render_block_core_archives( $attributes ) {
+ $show_post_count = ! empty( $attributes['showPostCounts'] );
+
+ $class = 'wp-block-archives';
+
+ if ( isset( $attributes['align'] ) ) {
+ $class .= " align{$attributes['align']}";
+ }
+
+ if ( isset( $attributes['className'] ) ) {
+ $class .= " {$attributes['className']}";
+ }
+
+ if ( ! empty( $attributes['displayAsDropdown'] ) ) {
+
+ $class .= ' wp-block-archives-dropdown';
+
+ $dropdown_id = esc_attr( uniqid( 'wp-block-archives-' ) );
+ $title = __( 'Archives' );
+
+ /** This filter is documented in wp-includes/widgets/class-wp-widget-archives.php */
+ $dropdown_args = apply_filters(
+ 'widget_archives_dropdown_args',
+ array(
+ 'type' => 'monthly',
+ 'format' => 'option',
+ 'show_post_count' => $show_post_count,
+ )
+ );
+
+ $dropdown_args['echo'] = 0;
+
+ $archives = wp_get_archives( $dropdown_args );
+
+ switch ( $dropdown_args['type'] ) {
+ case 'yearly':
+ $label = __( 'Select Year' );
+ break;
+ case 'monthly':
+ $label = __( 'Select Month' );
+ break;
+ case 'daily':
+ $label = __( 'Select Day' );
+ break;
+ case 'weekly':
+ $label = __( 'Select Week' );
+ break;
+ default:
+ $label = __( 'Select Post' );
+ break;
+ }
+
+ $label = esc_attr( $label );
+
+ $block_content = '<label class="screen-reader-text" for="' . $dropdown_id . '">' . $title . '</label>
+ <select id="' . $dropdown_id . '" name="archive-dropdown" onchange="document.location.href=this.options[this.selectedIndex].value;">
+ <option value="">' . $label . '</option>' . $archives . '</select>';
+
+ return sprintf(
+ '<div class="%1$s">%2$s</div>',
+ esc_attr( $class ),
+ $block_content
+ );
+ }
+
+ $class .= ' wp-block-archives-list';
+
+ /** This filter is documented in wp-includes/widgets/class-wp-widget-archives.php */
+ $archives_args = apply_filters(
+ 'widget_archives_args',
+ array(
+ 'type' => 'monthly',
+ 'show_post_count' => $show_post_count,
+ )
+ );
+
+ $archives_args['echo'] = 0;
+
+ $archives = wp_get_archives( $archives_args );
+
+ $classnames = esc_attr( $class );
+
+ if ( empty( $archives ) ) {
+
+ return sprintf(
+ '<div class="%1$s">%2$s</div>',
+ $classnames,
+ __( 'No archives to show.' )
+ );
+ }
+
+ return sprintf(
+ '<ul class="%1$s">%2$s</ul>',
+ $classnames,
+ $archives
+ );
+}
+
+/**
+ * Register archives block.
+ */
+function register_block_core_archives() {
+ register_block_type(
+ 'core/archives',
+ array(
+ 'attributes' => array(
+ 'align' => array(
+ 'type' => 'string',
+ 'enum' => array( 'left', 'center', 'right', 'wide', 'full' ),
+ ),
+ 'className' => array(
+ 'type' => 'string',
+ ),
+ 'displayAsDropdown' => array(
+ 'type' => 'boolean',
+ 'default' => false,
+ ),
+ 'showPostCounts' => array(
+ 'type' => 'boolean',
+ 'default' => false,
+ ),
+ ),
+ 'render_callback' => 'render_block_core_archives',
+ )
+ );
+}
+add_action( 'init', 'register_block_core_archives' );
diff --git a/srcs/wordpress/wp-includes/blocks/block.php b/srcs/wordpress/wp-includes/blocks/block.php
new file mode 100644
index 0000000..24d2ab5
--- /dev/null
+++ b/srcs/wordpress/wp-includes/blocks/block.php
@@ -0,0 +1,48 @@
+<?php
+/**
+ * Server-side rendering of the `core/block` block.
+ *
+ * @package WordPress
+ */
+
+/**
+ * Renders the `core/block` block on server.
+ *
+ * @param array $attributes The block attributes.
+ *
+ * @return string Rendered HTML of the referenced block.
+ */
+function render_block_core_block( $attributes ) {
+ if ( empty( $attributes['ref'] ) ) {
+ return '';
+ }
+
+ $reusable_block = get_post( $attributes['ref'] );
+ if ( ! $reusable_block || 'wp_block' !== $reusable_block->post_type ) {
+ return '';
+ }
+
+ if ( 'publish' !== $reusable_block->post_status || ! empty( $reusable_block->post_password ) ) {
+ return '';
+ }
+
+ return do_blocks( $reusable_block->post_content );
+}
+
+/**
+ * Registers the `core/block` block.
+ */
+function register_block_core_block() {
+ register_block_type(
+ 'core/block',
+ array(
+ 'attributes' => array(
+ 'ref' => array(
+ 'type' => 'number',
+ ),
+ ),
+ 'render_callback' => 'render_block_core_block',
+ )
+ );
+}
+add_action( 'init', 'register_block_core_block' );
diff --git a/srcs/wordpress/wp-includes/blocks/calendar.php b/srcs/wordpress/wp-includes/blocks/calendar.php
new file mode 100644
index 0000000..3d2e806
--- /dev/null
+++ b/srcs/wordpress/wp-includes/blocks/calendar.php
@@ -0,0 +1,78 @@
+<?php
+/**
+ * Server-side rendering of the `core/calendar` block.
+ *
+ * @package WordPress
+ */
+
+/**
+ * Renders the `core/calendar` block on server.
+ *
+ * @param array $attributes The block attributes.
+ *
+ * @return string Returns the block content.
+ */
+function render_block_core_calendar( $attributes ) {
+ global $monthnum, $year;
+
+ $previous_monthnum = $monthnum;
+ $previous_year = $year;
+
+ if ( isset( $attributes['month'] ) && isset( $attributes['year'] ) ) {
+ $permalink_structure = get_option( 'permalink_structure' );
+ if (
+ strpos( $permalink_structure, '%monthnum%' ) !== false &&
+ strpos( $permalink_structure, '%year%' ) !== false
+ ) {
+ // phpcs:ignore WordPress.WP.GlobalVariablesOverride.OverrideProhibited
+ $monthnum = $attributes['month'];
+ // phpcs:ignore WordPress.WP.GlobalVariablesOverride.OverrideProhibited
+ $year = $attributes['year'];
+ }
+ }
+
+ $custom_class_name = empty( $attributes['className'] ) ? '' : ' ' . $attributes['className'];
+ $align_class_name = empty( $attributes['align'] ) ? '' : ' ' . "align{$attributes['align']}";
+
+ $output = sprintf(
+ '<div class="%1$s">%2$s</div>',
+ esc_attr( 'wp-block-calendar' . $custom_class_name . $align_class_name ),
+ get_calendar( true, false )
+ );
+
+ // phpcs:ignore WordPress.WP.GlobalVariablesOverride.OverrideProhibited
+ $monthnum = $previous_monthnum;
+ // phpcs:ignore WordPress.WP.GlobalVariablesOverride.OverrideProhibited
+ $year = $previous_year;
+
+ return $output;
+}
+
+/**
+ * Registers the `core/calendar` block on server.
+ */
+function register_block_core_calendar() {
+ register_block_type(
+ 'core/calendar',
+ array(
+ 'attributes' => array(
+ 'align' => array(
+ 'type' => 'string',
+ 'enum' => array( 'left', 'center', 'right', 'wide', 'full' ),
+ ),
+ 'className' => array(
+ 'type' => 'string',
+ ),
+ 'month' => array(
+ 'type' => 'integer',
+ ),
+ 'year' => array(
+ 'type' => 'integer',
+ ),
+ ),
+ 'render_callback' => 'render_block_core_calendar',
+ )
+ );
+}
+
+add_action( 'init', 'register_block_core_calendar' );
diff --git a/srcs/wordpress/wp-includes/blocks/categories.php b/srcs/wordpress/wp-includes/blocks/categories.php
new file mode 100644
index 0000000..159bb8b
--- /dev/null
+++ b/srcs/wordpress/wp-includes/blocks/categories.php
@@ -0,0 +1,120 @@
+<?php
+/**
+ * Server-side rendering of the `core/categories` block.
+ *
+ * @package WordPress
+ */
+
+/**
+ * Renders the `core/categories` block on server.
+ *
+ * @param array $attributes The block attributes.
+ *
+ * @return string Returns the categories list/dropdown markup.
+ */
+function render_block_core_categories( $attributes ) {
+ static $block_id = 0;
+ $block_id++;
+
+ $args = array(
+ 'echo' => false,
+ 'hierarchical' => ! empty( $attributes['showHierarchy'] ),
+ 'orderby' => 'name',
+ 'show_count' => ! empty( $attributes['showPostCounts'] ),
+ 'title_li' => '',
+ );
+
+ if ( ! empty( $attributes['displayAsDropdown'] ) ) {
+ $id = 'wp-block-categories-' . $block_id;
+ $args['id'] = $id;
+ $args['show_option_none'] = __( 'Select Category' );
+ $wrapper_markup = '<div class="%1$s">%2$s</div>';
+ $items_markup = wp_dropdown_categories( $args );
+ $type = 'dropdown';
+
+ if ( ! is_admin() ) {
+ $wrapper_markup .= build_dropdown_script_block_core_categories( $id );
+ }
+ } else {
+ $wrapper_markup = '<ul class="%1$s">%2$s</ul>';
+ $items_markup = wp_list_categories( $args );
+ $type = 'list';
+ }
+
+ $class = "wp-block-categories wp-block-categories-{$type}";
+
+ if ( isset( $attributes['align'] ) ) {
+ $class .= " align{$attributes['align']}";
+ }
+
+ if ( isset( $attributes['className'] ) ) {
+ $class .= " {$attributes['className']}";
+ }
+
+ return sprintf(
+ $wrapper_markup,
+ esc_attr( $class ),
+ $items_markup
+ );
+}
+
+/**
+ * Generates the inline script for a categories dropdown field.
+ *
+ * @param string $dropdown_id ID of the dropdown field.
+ *
+ * @return string Returns the dropdown onChange redirection script.
+ */
+function build_dropdown_script_block_core_categories( $dropdown_id ) {
+ ob_start();
+ ?>
+ <script type='text/javascript'>
+ /* <![CDATA[ */
+ ( function() {
+ var dropdown = document.getElementById( '<?php echo esc_js( $dropdown_id ); ?>' );
+ function onCatChange() {
+ if ( dropdown.options[ dropdown.selectedIndex ].value > 0 ) {
+ location.href = "<?php echo home_url(); ?>/?cat=" + dropdown.options[ dropdown.selectedIndex ].value;
+ }
+ }
+ dropdown.onchange = onCatChange;
+ })();
+ /* ]]> */
+ </script>
+ <?php
+ return ob_get_clean();
+}
+
+/**
+ * Registers the `core/categories` block on server.
+ */
+function register_block_core_categories() {
+ register_block_type(
+ 'core/categories',
+ array(
+ 'attributes' => array(
+ 'align' => array(
+ 'type' => 'string',
+ 'enum' => array( 'left', 'center', 'right', 'wide', 'full' ),
+ ),
+ 'className' => array(
+ 'type' => 'string',
+ ),
+ 'displayAsDropdown' => array(
+ 'type' => 'boolean',
+ 'default' => false,
+ ),
+ 'showHierarchy' => array(
+ 'type' => 'boolean',
+ 'default' => false,
+ ),
+ 'showPostCounts' => array(
+ 'type' => 'boolean',
+ 'default' => false,
+ ),
+ ),
+ 'render_callback' => 'render_block_core_categories',
+ )
+ );
+}
+add_action( 'init', 'register_block_core_categories' );
diff --git a/srcs/wordpress/wp-includes/blocks/latest-comments.php b/srcs/wordpress/wp-includes/blocks/latest-comments.php
new file mode 100644
index 0000000..d68e89a
--- /dev/null
+++ b/srcs/wordpress/wp-includes/blocks/latest-comments.php
@@ -0,0 +1,196 @@
+<?php
+/**
+ * Server-side rendering of the `core/latest-comments` block.
+ *
+ * @package WordPress
+ */
+
+/**
+ * Get the post title.
+ *
+ * The post title is fetched and if it is blank then a default string is
+ * returned.
+ *
+ * Copied from `wp-admin/includes/template.php`, but we can't include that
+ * file because:
+ *
+ * 1. It causes bugs with test fixture generation and strange Docker 255 error
+ * codes.
+ * 2. It's in the admin; ideally we *shouldn't* be including files from the
+ * admin for a block's output. It's a very small/simple function as well,
+ * so duplicating it isn't too terrible.
+ *
+ * @since 3.3.0
+ *
+ * @param int|WP_Post $post Optional. Post ID or WP_Post object. Default is global $post.
+ * @return string The post title if set; "(no title)" if no title is set.
+ */
+function wp_latest_comments_draft_or_post_title( $post = 0 ) {
+ $title = get_the_title( $post );
+ if ( empty( $title ) ) {
+ $title = __( '(no title)' );
+ }
+ return esc_html( $title );
+}
+
+/**
+ * Renders the `core/latest-comments` block on server.
+ *
+ * @param array $attributes The block attributes.
+ *
+ * @return string Returns the post content with latest comments added.
+ */
+function render_block_core_latest_comments( $attributes = array() ) {
+ // This filter is documented in wp-includes/widgets/class-wp-widget-recent-comments.php.
+ $comments = get_comments(
+ apply_filters(
+ 'widget_comments_args',
+ array(
+ 'number' => $attributes['commentsToShow'],
+ 'status' => 'approve',
+ 'post_status' => 'publish',
+ )
+ )
+ );
+
+ $list_items_markup = '';
+ if ( ! empty( $comments ) ) {
+ // Prime the cache for associated posts. This is copied from \WP_Widget_Recent_Comments::widget().
+ $post_ids = array_unique( wp_list_pluck( $comments, 'comment_post_ID' ) );
+ _prime_post_caches( $post_ids, strpos( get_option( 'permalink_structure' ), '%category%' ), false );
+
+ foreach ( $comments as $comment ) {
+ $list_items_markup .= '<li class="wp-block-latest-comments__comment">';
+ if ( $attributes['displayAvatar'] ) {
+ $avatar = get_avatar(
+ $comment,
+ 48,
+ '',
+ '',
+ array(
+ 'class' => 'wp-block-latest-comments__comment-avatar',
+ )
+ );
+ if ( $avatar ) {
+ $list_items_markup .= $avatar;
+ }
+ }
+
+ $list_items_markup .= '<article>';
+ $list_items_markup .= '<footer class="wp-block-latest-comments__comment-meta">';
+ $author_url = get_comment_author_url( $comment );
+ if ( empty( $author_url ) && ! empty( $comment->user_id ) ) {
+ $author_url = get_author_posts_url( $comment->user_id );
+ }
+
+ $author_markup = '';
+ if ( $author_url ) {
+ $author_markup .= '<a class="wp-block-latest-comments__comment-author" href="' . esc_url( $author_url ) . '">' . get_comment_author( $comment ) . '</a>';
+ } else {
+ $author_markup .= '<span class="wp-block-latest-comments__comment-author">' . get_comment_author( $comment ) . '</span>';
+ }
+
+ // `_draft_or_post_title` calls `esc_html()` so we don't need to wrap that call in
+ // `esc_html`.
+ $post_title = '<a class="wp-block-latest-comments__comment-link" href="' . esc_url( get_comment_link( $comment ) ) . '">' . wp_latest_comments_draft_or_post_title( $comment->comment_post_ID ) . '</a>';
+
+ $list_items_markup .= sprintf(
+ /* translators: 1: author name (inside <a> or <span> tag, based on if they have a URL), 2: post title related to this comment */
+ __( '%1$s on %2$s' ),
+ $author_markup,
+ $post_title
+ );
+
+ if ( $attributes['displayDate'] ) {
+ $list_items_markup .= sprintf(
+ '<time datetime="%1$s" class="wp-block-latest-comments__comment-date">%2$s</time>',
+ esc_attr( get_comment_date( 'c', $comment ) ),
+ date_i18n( get_option( 'date_format' ), get_comment_date( 'U', $comment ) )
+ );
+ }
+ $list_items_markup .= '</footer>';
+ if ( $attributes['displayExcerpt'] ) {
+ $list_items_markup .= '<div class="wp-block-latest-comments__comment-excerpt">' . wpautop( get_comment_excerpt( $comment ) ) . '</div>';
+ }
+ $list_items_markup .= '</article></li>';
+ }
+ }
+
+ $class = 'wp-block-latest-comments';
+ if ( ! empty( $attributes['className'] ) ) {
+ $class .= ' ' . $attributes['className'];
+ }
+ if ( isset( $attributes['align'] ) ) {
+ $class .= " align{$attributes['align']}";
+ }
+ if ( $attributes['displayAvatar'] ) {
+ $class .= ' has-avatars';
+ }
+ if ( $attributes['displayDate'] ) {
+ $class .= ' has-dates';
+ }
+ if ( $attributes['displayExcerpt'] ) {
+ $class .= ' has-excerpts';
+ }
+ if ( empty( $comments ) ) {
+ $class .= ' no-comments';
+ }
+ $classnames = esc_attr( $class );
+
+ return ! empty( $comments ) ? sprintf(
+ '<ol class="%1$s">%2$s</ol>',
+ $classnames,
+ $list_items_markup
+ ) : sprintf(
+ '<div class="%1$s">%2$s</div>',
+ $classnames,
+ __( 'No comments to show.' )
+ );
+}
+
+/**
+ * Registers the `core/latest-comments` block.
+ */
+function register_block_core_latest_comments() {
+ register_block_type(
+ 'core/latest-comments',
+ array(
+ 'attributes' => array(
+ 'align' => array(
+ 'type' => 'string',
+ 'enum' => array(
+ 'left',
+ 'center',
+ 'right',
+ 'wide',
+ 'full',
+ ),
+ ),
+ 'className' => array(
+ 'type' => 'string',
+ ),
+ 'commentsToShow' => array(
+ 'type' => 'number',
+ 'default' => 5,
+ 'minimum' => 1,
+ 'maximum' => 100,
+ ),
+ 'displayAvatar' => array(
+ 'type' => 'boolean',
+ 'default' => true,
+ ),
+ 'displayDate' => array(
+ 'type' => 'boolean',
+ 'default' => true,
+ ),
+ 'displayExcerpt' => array(
+ 'type' => 'boolean',
+ 'default' => true,
+ ),
+ ),
+ 'render_callback' => 'render_block_core_latest_comments',
+ )
+ );
+}
+
+add_action( 'init', 'register_block_core_latest_comments' );
diff --git a/srcs/wordpress/wp-includes/blocks/latest-posts.php b/srcs/wordpress/wp-includes/blocks/latest-posts.php
new file mode 100644
index 0000000..b8fc02c
--- /dev/null
+++ b/srcs/wordpress/wp-includes/blocks/latest-posts.php
@@ -0,0 +1,177 @@
+<?php
+/**
+ * Server-side rendering of the `core/latest-posts` block.
+ *
+ * @package WordPress
+ */
+
+/**
+ * Renders the `core/latest-posts` block on server.
+ *
+ * @param array $attributes The block attributes.
+ *
+ * @return string Returns the post content with latest posts added.
+ */
+function render_block_core_latest_posts( $attributes ) {
+ $args = array(
+ 'posts_per_page' => $attributes['postsToShow'],
+ 'post_status' => 'publish',
+ 'order' => $attributes['order'],
+ 'orderby' => $attributes['orderBy'],
+ 'suppress_filters' => false,
+ );
+
+ if ( isset( $attributes['categories'] ) ) {
+ $args['category'] = $attributes['categories'];
+ }
+
+ $recent_posts = get_posts( $args );
+
+ $list_items_markup = '';
+
+ $excerpt_length = $attributes['excerptLength'];
+
+ foreach ( $recent_posts as $post ) {
+ $title = get_the_title( $post );
+ if ( ! $title ) {
+ $title = __( '(no title)' );
+ }
+ $list_items_markup .= sprintf(
+ '<li><a href="%1$s">%2$s</a>',
+ esc_url( get_permalink( $post ) ),
+ $title
+ );
+
+ if ( isset( $attributes['displayPostDate'] ) && $attributes['displayPostDate'] ) {
+ $list_items_markup .= sprintf(
+ '<time datetime="%1$s" class="wp-block-latest-posts__post-date">%2$s</time>',
+ esc_attr( get_the_date( 'c', $post ) ),
+ esc_html( get_the_date( '', $post ) )
+ );
+ }
+
+ if ( isset( $attributes['displayPostContent'] ) && $attributes['displayPostContent']
+ && isset( $attributes['displayPostContentRadio'] ) && 'excerpt' === $attributes['displayPostContentRadio'] ) {
+ $post_excerpt = $post->post_excerpt;
+ if ( ! ( $post_excerpt ) ) {
+ $post_excerpt = $post->post_content;
+ }
+ $trimmed_excerpt = esc_html( wp_trim_words( $post_excerpt, $excerpt_length, ' &hellip; ' ) );
+
+ $list_items_markup .= sprintf(
+ '<div class="wp-block-latest-posts__post-excerpt">%1$s',
+ $trimmed_excerpt
+ );
+
+ if ( strpos( $trimmed_excerpt, ' &hellip; ' ) !== false ) {
+ $list_items_markup .= sprintf(
+ '<a href="%1$s">%2$s</a></div>',
+ esc_url( get_permalink( $post ) ),
+ __( 'Read more' )
+ );
+ } else {
+ $list_items_markup .= sprintf(
+ '</div>'
+ );
+ }
+ }
+
+ if ( isset( $attributes['displayPostContent'] ) && $attributes['displayPostContent']
+ && isset( $attributes['displayPostContentRadio'] ) && 'full_post' === $attributes['displayPostContentRadio'] ) {
+ $list_items_markup .= sprintf(
+ '<div class="wp-block-latest-posts__post-full-content">%1$s</div>',
+ wp_kses_post( html_entity_decode( $post->post_content, ENT_QUOTES, get_option( 'blog_charset' ) ) )
+ );
+ }
+
+ $list_items_markup .= "</li>\n";
+ }
+
+ $class = 'wp-block-latest-posts wp-block-latest-posts__list';
+ if ( isset( $attributes['align'] ) ) {
+ $class .= ' align' . $attributes['align'];
+ }
+
+ if ( isset( $attributes['postLayout'] ) && 'grid' === $attributes['postLayout'] ) {
+ $class .= ' is-grid';
+ }
+
+ if ( isset( $attributes['columns'] ) && 'grid' === $attributes['postLayout'] ) {
+ $class .= ' columns-' . $attributes['columns'];
+ }
+
+ if ( isset( $attributes['displayPostDate'] ) && $attributes['displayPostDate'] ) {
+ $class .= ' has-dates';
+ }
+
+ if ( isset( $attributes['className'] ) ) {
+ $class .= ' ' . $attributes['className'];
+ }
+
+ return sprintf(
+ '<ul class="%1$s">%2$s</ul>',
+ esc_attr( $class ),
+ $list_items_markup
+ );
+}
+
+/**
+ * Registers the `core/latest-posts` block on server.
+ */
+function register_block_core_latest_posts() {
+ register_block_type(
+ 'core/latest-posts',
+ array(
+ 'attributes' => array(
+ 'align' => array(
+ 'type' => 'string',
+ 'enum' => array( 'left', 'center', 'right', 'wide', 'full' ),
+ ),
+ 'className' => array(
+ 'type' => 'string',
+ ),
+ 'categories' => array(
+ 'type' => 'string',
+ ),
+ 'postsToShow' => array(
+ 'type' => 'number',
+ 'default' => 5,
+ ),
+ 'displayPostContent' => array(
+ 'type' => 'boolean',
+ 'default' => false,
+ ),
+ 'displayPostContentRadio' => array(
+ 'type' => 'string',
+ 'default' => 'excerpt',
+ ),
+ 'excerptLength' => array(
+ 'type' => 'number',
+ 'default' => 55,
+ ),
+ 'displayPostDate' => array(
+ 'type' => 'boolean',
+ 'default' => false,
+ ),
+ 'postLayout' => array(
+ 'type' => 'string',
+ 'default' => 'list',
+ ),
+ 'columns' => array(
+ 'type' => 'number',
+ 'default' => 3,
+ ),
+ 'order' => array(
+ 'type' => 'string',
+ 'default' => 'desc',
+ ),
+ 'orderBy' => array(
+ 'type' => 'string',
+ 'default' => 'date',
+ ),
+ ),
+ 'render_callback' => 'render_block_core_latest_posts',
+ )
+ );
+}
+add_action( 'init', 'register_block_core_latest_posts' );
diff --git a/srcs/wordpress/wp-includes/blocks/rss.php b/srcs/wordpress/wp-includes/blocks/rss.php
new file mode 100644
index 0000000..0300585
--- /dev/null
+++ b/srcs/wordpress/wp-includes/blocks/rss.php
@@ -0,0 +1,160 @@
+<?php
+/**
+ * Server-side rendering of the `core/rss` block.
+ *
+ * @package WordPress
+ */
+
+/**
+ * Renders the `core/rss` block on server.
+ *
+ * @param array $attributes The block attributes.
+ *
+ * @return string Returns the block content with received rss items.
+ */
+function render_block_core_rss( $attributes ) {
+ $rss = fetch_feed( $attributes['feedURL'] );
+
+ if ( is_wp_error( $rss ) ) {
+ return '<div class="components-placeholder"><div class="notice notice-error"><strong>' . __( 'RSS Error:' ) . '</strong> ' . $rss->get_error_message() . '</div></div>';
+ }
+
+ if ( ! $rss->get_item_quantity() ) {
+ // PHP 5.2 compatibility. See: http://simplepie.org/wiki/faq/i_m_getting_memory_leaks.
+ $rss->__destruct();
+ unset( $rss );
+
+ return '<div class="components-placeholder"><div class="notice notice-error">' . __( 'An error has occurred, which probably means the feed is down. Try again later.' ) . '</div></div>';
+ }
+
+ $rss_items = $rss->get_items( 0, $attributes['itemsToShow'] );
+ $list_items = '';
+ foreach ( $rss_items as $item ) {
+ $title = esc_html( trim( strip_tags( $item->get_title() ) ) );
+ if ( empty( $title ) ) {
+ $title = __( '(no title)' );
+ }
+ $link = $item->get_link();
+ $link = esc_url( $link );
+ if ( $link ) {
+ $title = "<a href='{$link}'>{$title}</a>";
+ }
+ $title = "<div class='wp-block-rss__item-title'>{$title}</div>";
+
+ $date = '';
+ if ( $attributes['displayDate'] ) {
+ $date = $item->get_date( 'U' );
+
+ if ( $date ) {
+ $date = sprintf(
+ '<time datetime="%1$s" class="wp-block-rss__item-publish-date">%2$s</time> ',
+ date_i18n( get_option( 'c' ), $date ),
+ date_i18n( get_option( 'date_format' ), $date )
+ );
+ }
+ }
+
+ $author = '';
+ if ( $attributes['displayAuthor'] ) {
+ $author = $item->get_author();
+ if ( is_object( $author ) ) {
+ $author = $author->get_name();
+ $author = '<span class="wp-block-rss__item-author">' . __( 'by' ) . ' ' . esc_html( strip_tags( $author ) ) . '</span>';
+ }
+ }
+
+ $excerpt = '';
+ if ( $attributes['displayExcerpt'] ) {
+ $excerpt = html_entity_decode( $item->get_description(), ENT_QUOTES, get_option( 'blog_charset' ) );
+ $excerpt = esc_attr( wp_trim_words( $excerpt, $attributes['excerptLength'], ' [&hellip;]' ) );
+
+ // Change existing [...] to [&hellip;].
+ if ( '[...]' === substr( $excerpt, -5 ) ) {
+ $excerpt = substr( $excerpt, 0, -5 ) . '[&hellip;]';
+ }
+
+ $excerpt = '<div class="wp-block-rss__item-excerpt">' . esc_html( $excerpt ) . '</div>';
+ }
+
+ $list_items .= "<li class='wp-block-rss__item'>{$title}{$date}{$author}{$excerpt}</li>";
+ }
+
+ $class = 'wp-block-rss';
+ if ( isset( $attributes['align'] ) ) {
+ $class .= ' align' . $attributes['align'];
+ }
+
+ if ( isset( $attributes['blockLayout'] ) && 'grid' === $attributes['blockLayout'] ) {
+ $class .= ' is-grid';
+ }
+
+ if ( isset( $attributes['columns'] ) && 'grid' === $attributes['blockLayout'] ) {
+ $class .= ' columns-' . $attributes['columns'];
+ }
+
+ if ( isset( $attributes['className'] ) ) {
+ $class .= ' ' . $attributes['className'];
+ }
+
+ $list_items_markup = "<ul class='{$class}'>{$list_items}</ul>";
+
+ // PHP 5.2 compatibility. See: http://simplepie.org/wiki/faq/i_m_getting_memory_leaks.
+ $rss->__destruct();
+ unset( $rss );
+
+ return $list_items_markup;
+}
+
+/**
+ * Registers the `core/rss` block on server.
+ */
+function register_block_core_rss() {
+ register_block_type(
+ 'core/rss',
+ array(
+ 'attributes' => array(
+ 'align' => array(
+ 'type' => 'string',
+ 'enum' => array( 'left', 'center', 'right', 'wide', 'full' ),
+ ),
+ 'className' => array(
+ 'type' => 'string',
+ ),
+ 'columns' => array(
+ 'type' => 'number',
+ 'default' => 2,
+ ),
+ 'blockLayout' => array(
+ 'type' => 'string',
+ 'default' => 'list',
+ ),
+ 'feedURL' => array(
+ 'type' => 'string',
+ 'default' => '',
+ ),
+ 'itemsToShow' => array(
+ 'type' => 'number',
+ 'default' => 5,
+ ),
+ 'displayExcerpt' => array(
+ 'type' => 'boolean',
+ 'default' => false,
+ ),
+ 'displayAuthor' => array(
+ 'type' => 'boolean',
+ 'default' => false,
+ ),
+ 'displayDate' => array(
+ 'type' => 'boolean',
+ 'default' => false,
+ ),
+ 'excerptLength' => array(
+ 'type' => 'number',
+ 'default' => 55,
+ ),
+ ),
+ 'render_callback' => 'render_block_core_rss',
+ )
+ );
+}
+add_action( 'init', 'register_block_core_rss' );
diff --git a/srcs/wordpress/wp-includes/blocks/search.php b/srcs/wordpress/wp-includes/blocks/search.php
new file mode 100644
index 0000000..6cd909f
--- /dev/null
+++ b/srcs/wordpress/wp-includes/blocks/search.php
@@ -0,0 +1,93 @@
+<?php
+/**
+ * Server-side rendering of the `core/search` block.
+ *
+ * @package WordPress
+ */
+
+/**
+ * Dynamically renders the `core/search` block.
+ *
+ * @param array $attributes The block attributes.
+ *
+ * @return string The search block markup.
+ */
+function render_block_core_search( $attributes ) {
+ static $instance_id = 0;
+
+ $input_id = 'wp-block-search__input-' . ++$instance_id;
+ $label_markup = '';
+ $button_markup = '';
+
+ if ( ! empty( $attributes['label'] ) ) {
+ $label_markup = sprintf(
+ '<label for="%s" class="wp-block-search__label">%s</label>',
+ $input_id,
+ $attributes['label']
+ );
+ }
+
+ $input_markup = sprintf(
+ '<input type="search" id="%s" class="wp-block-search__input" name="s" value="%s" placeholder="%s" />',
+ $input_id,
+ esc_attr( get_search_query() ),
+ esc_attr( $attributes['placeholder'] )
+ );
+
+ if ( ! empty( $attributes['buttonText'] ) ) {
+ $button_markup = sprintf(
+ '<button type="submit" class="wp-block-search__button">%s</button>',
+ $attributes['buttonText']
+ );
+ }
+
+ $class = 'wp-block-search';
+ if ( isset( $attributes['className'] ) ) {
+ $class .= ' ' . $attributes['className'];
+ }
+
+ if ( isset( $attributes['align'] ) ) {
+ $class .= ' align' . $attributes['align'];
+ }
+
+ return sprintf(
+ '<form class="%s" role="search" method="get" action="%s">%s</form>',
+ $class,
+ esc_url( home_url( '/' ) ),
+ $label_markup . $input_markup . $button_markup
+ );
+}
+
+/**
+ * Registers the `core/search` block on the server.
+ */
+function register_block_core_search() {
+ register_block_type(
+ 'core/search',
+ array(
+ 'attributes' => array(
+ 'align' => array(
+ 'type' => 'string',
+ 'enum' => array( 'left', 'center', 'right', 'wide', 'full' ),
+ ),
+ 'className' => array(
+ 'type' => 'string',
+ ),
+ 'label' => array(
+ 'type' => 'string',
+ 'default' => __( 'Search' ),
+ ),
+ 'placeholder' => array(
+ 'type' => 'string',
+ 'default' => '',
+ ),
+ 'buttonText' => array(
+ 'type' => 'string',
+ 'default' => __( 'Search' ),
+ ),
+ ),
+ 'render_callback' => 'render_block_core_search',
+ )
+ );
+}
+add_action( 'init', 'register_block_core_search' );
diff --git a/srcs/wordpress/wp-includes/blocks/shortcode.php b/srcs/wordpress/wp-includes/blocks/shortcode.php
new file mode 100644
index 0000000..79df091
--- /dev/null
+++ b/srcs/wordpress/wp-includes/blocks/shortcode.php
@@ -0,0 +1,37 @@
+<?php
+/**
+ * Server-side rendering of the `core/shortcode` block.
+ *
+ * @package WordPress
+ */
+
+/**
+ * Performs wpautop() on the shortcode block content.
+ *
+ * @param array $attributes The block attributes.
+ * @param string $content The block content.
+ *
+ * @return string Returns the block content.
+ */
+function render_block_core_shortcode( $attributes, $content ) {
+ return wpautop( $content );
+}
+
+/**
+ * Registers the `core/shortcode` block on server.
+ */
+function register_block_core_shortcode() {
+ register_block_type(
+ 'core/shortcode',
+ array(
+ 'attributes' => array(
+ 'text' => array(
+ 'type' => 'string',
+ 'source' => 'html',
+ ),
+ ),
+ 'render_callback' => 'render_block_core_shortcode',
+ )
+ );
+}
+add_action( 'init', 'register_block_core_shortcode' );
diff --git a/srcs/wordpress/wp-includes/blocks/tag-cloud.php b/srcs/wordpress/wp-includes/blocks/tag-cloud.php
new file mode 100644
index 0000000..cf9c4d2
--- /dev/null
+++ b/srcs/wordpress/wp-includes/blocks/tag-cloud.php
@@ -0,0 +1,78 @@
+<?php
+/**
+ * Server-side rendering of the `core/tag-cloud` block.
+ *
+ * @package WordPress
+ */
+
+/**
+ * Renders the `core/tag-cloud` block on server.
+ *
+ * @param array $attributes The block attributes.
+ *
+ * @return string Returns the tag cloud for selected taxonomy.
+ */
+function render_block_core_tag_cloud( $attributes ) {
+ $class = isset( $attributes['align'] ) ?
+ "wp-block-tag-cloud align{$attributes['align']}" :
+ 'wp-block-tag-cloud';
+
+ if ( isset( $attributes['className'] ) ) {
+ $class .= ' ' . $attributes['className'];
+ }
+
+ $args = array(
+ 'echo' => false,
+ 'taxonomy' => $attributes['taxonomy'],
+ 'show_count' => $attributes['showTagCounts'],
+ );
+
+ $tag_cloud = wp_tag_cloud( $args );
+
+ if ( ! $tag_cloud ) {
+ $labels = get_taxonomy_labels( get_taxonomy( $attributes['taxonomy'] ) );
+ $tag_cloud = esc_html(
+ sprintf(
+ /* translators: %s: taxonomy name */
+ __( 'Your site doesn&#8217;t have any %s, so there&#8217;s nothing to display here at the moment.' ),
+ strtolower( $labels->name )
+ )
+ );
+ }
+
+ return sprintf(
+ '<p class="%1$s">%2$s</p>',
+ esc_attr( $class ),
+ $tag_cloud
+ );
+}
+
+/**
+ * Registers the `core/tag-cloud` block on server.
+ */
+function register_block_core_tag_cloud() {
+ register_block_type(
+ 'core/tag-cloud',
+ array(
+ 'attributes' => array(
+ 'align' => array(
+ 'type' => 'string',
+ 'enum' => array( 'left', 'center', 'right', 'wide', 'full' ),
+ ),
+ 'className' => array(
+ 'type' => 'string',
+ ),
+ 'taxonomy' => array(
+ 'type' => 'string',
+ 'default' => 'post_tag',
+ ),
+ 'showTagCounts' => array(
+ 'type' => 'boolean',
+ 'default' => false,
+ ),
+ ),
+ 'render_callback' => 'render_block_core_tag_cloud',
+ )
+ );
+}
+add_action( 'init', 'register_block_core_tag_cloud' );