init commit

This commit is contained in:
2024-06-05 17:37:13 +00:00
commit 7a1361419a
52 changed files with 2693 additions and 0 deletions

31
theme/404.php Normal file
View File

@@ -0,0 +1,31 @@
<?php
/**
* The template for displaying 404 pages (not found)
*
* @link https://codex.wordpress.org/Creating_an_Error_404_Page
*
* @package Valier
*/
get_header();
?>
<section id="primary">
<main id="main">
<div>
<header class="page-header">
<h1 class="page-title"><?php esc_html_e( 'Page Not Found', 'valier' ); ?></h1>
</header><!-- .page-header -->
<div <?php vlr_content_class( 'page-content' ); ?>>
<p><?php esc_html_e( 'This page could not be found. It might have been removed or renamed, or it may never have existed.', 'valier' ); ?></p>
<?php get_search_form(); ?>
</div><!-- .page-content -->
</div>
</main><!-- #main -->
</section><!-- #primary -->
<?php
get_footer();

45
theme/archive.php Normal file
View File

@@ -0,0 +1,45 @@
<?php
/**
* The template for displaying archive pages
*
* @link https://developer.wordpress.org/themes/basics/template-hierarchy/
*
* @package Valier
*/
get_header();
?>
<section id="primary">
<main id="main">
<?php if ( have_posts() ) : ?>
<header class="page-header">
<?php the_archive_title( '<h1 class="page-title">', '</h1>' ); ?>
</header><!-- .page-header -->
<?php
// Start the Loop.
while ( have_posts() ) :
the_post();
get_template_part( 'template-parts/content/content', 'excerpt' );
// End the loop.
endwhile;
// Previous/next page navigation.
vlr_the_posts_navigation();
else :
// If no content, include the "No posts found" template.
get_template_part( 'template-parts/content/content', 'none' );
endif;
?>
</main><!-- #main -->
</section><!-- #primary -->
<?php
get_footer();

81
theme/comments.php Normal file
View File

@@ -0,0 +1,81 @@
<?php
/**
* The template for displaying comments
*
* This is the template that displays the area of the page that contains both
* the current comments and the comment form.
*
* @link https://developer.wordpress.org/themes/basics/template-hierarchy/
*
* @package Valier
*/
/*
* If the current post is protected by a password and the visitor has not yet
* entered the password we will return early without loading the comments.
*/
if ( post_password_required() ) {
return;
}
?>
<div id="comments">
<?php
if ( have_comments() ) :
?>
<h2>
<?php
$vlr_comment_count = get_comments_number();
if ( '1' === $vlr_comment_count ) {
// phpcs:disable WordPress.Security.EscapeOutput.OutputNotEscaped
printf(
/* translators: 1: title. */
esc_html__( 'One comment on &ldquo;%1$s&rdquo;', 'valier' ),
get_the_title()
);
// phpcs:enable WordPress.Security.EscapeOutput.OutputNotEscaped
} else {
// phpcs:disable WordPress.Security.EscapeOutput.OutputNotEscaped
printf(
/* translators: 1: comment count number, 2: title. */
esc_html( _nx( '%1$s comment on &ldquo;%2$s&rdquo;', '%1$s comments on &ldquo;%2$s&rdquo;', $vlr_comment_count, 'comments title', 'valier' ) ),
number_format_i18n( $vlr_comment_count ),
get_the_title()
);
// phpcs:enable WordPress.Security.EscapeOutput.OutputNotEscaped
}
?>
</h2>
<?php the_comments_navigation(); ?>
<ol>
<?php
wp_list_comments(
array(
'style' => 'ol',
'callback' => 'vlr_html5_comment',
'short_ping' => true,
)
);
?>
</ol>
<?php
the_comments_navigation();
// If there are existing comments, but comments are closed, display a
// message.
if ( ! comments_open() ) :
?>
<p><?php esc_html_e( 'Comments are closed.', 'valier' ); ?></p>
<?php
endif;
endif;
comment_form();
?>
</div><!-- #comments -->

23
theme/footer.php Normal file
View File

@@ -0,0 +1,23 @@
<?php
/**
* The template for displaying the footer
*
* Contains the closing of the `#content` element and all content thereafter.
*
* @link https://developer.wordpress.org/themes/basics/template-files/#template-partials
*
* @package Valier
*/
?>
</div><!-- #content -->
<?php get_template_part( 'template-parts/layout/footer', 'content' ); ?>
</div><!-- #page -->
<?php wp_footer(); ?>
</body>
</html>

197
theme/functions.php Normal file
View File

@@ -0,0 +1,197 @@
<?php
/**
* Valier functions and definitions
*
* @link https://developer.wordpress.org/themes/basics/theme-functions/
*
* @package Valier
*/
if ( ! defined( 'VLR_VERSION' ) ) {
/*
* Set the themes version number.
*
* This is used primarily for cache busting. If you use `npm run bundle`
* to create your production build, the value below will be replaced in the
* generated zip file with a timestamp, converted to base 36.
*/
define( 'VLR_VERSION', '0.1.0' );
}
if ( ! defined( 'VLR_TYPOGRAPHY_CLASSES' ) ) {
/*
* Set Tailwind Typography classes for the front end, block editor and
* classic editor using the constant below.
*
* For the front end, these classes are added by the `vlr_content_class`
* function. You will see that function used everywhere an `entry-content`
* or `page-content` class has been added to a wrapper element.
*
* For the block editor, these classes are converted to a JavaScript array
* and then used by the `./javascript/block-editor.js` file, which adds
* them to the appropriate elements in the block editor (and adds them
* again when theyre removed.)
*
* For the classic editor (and anything using TinyMCE, like Advanced Custom
* Fields), these classes are added to TinyMCEs body class when it
* initializes.
*/
define(
'VLR_TYPOGRAPHY_CLASSES',
'prose prose-neutral max-w-none prose-a:text-primary'
);
}
if ( ! function_exists( 'vlr_setup' ) ) :
/**
* Sets up theme defaults and registers support for various WordPress features.
*
* Note that this function is hooked into the after_setup_theme hook, which
* runs before the init hook. The init hook is too late for some features, such
* as indicating support for post thumbnails.
*/
function vlr_setup() {
/*
* Make theme available for translation.
* Translations can be filed in the /languages/ directory.
* If you're building a theme based on Valier, use a find and replace
* to change 'valier' to the name of your theme in all the template files.
*/
load_theme_textdomain( 'valier', get_template_directory() . '/languages' );
// Add default posts and comments RSS feed links to head.
add_theme_support( 'automatic-feed-links' );
/*
* Let WordPress manage the document title.
* By adding theme support, we declare that this theme does not use a
* hard-coded <title> tag in the document head, and expect WordPress to
* provide it for us.
*/
add_theme_support( 'title-tag' );
/*
* Enable support for Post Thumbnails on posts and pages.
*
* @link https://developer.wordpress.org/themes/functionality/featured-images-post-thumbnails/
*/
add_theme_support( 'post-thumbnails' );
// This theme uses wp_nav_menu() in two locations.
register_nav_menus(
array(
'menu-1' => __( 'Primary', 'valier' ),
'menu-2' => __( 'Footer Menu', 'valier' ),
)
);
/*
* Switch default core markup for search form, comment form, and comments
* to output valid HTML5.
*/
add_theme_support(
'html5',
array(
'search-form',
'comment-form',
'comment-list',
'gallery',
'caption',
'style',
'script',
)
);
// Add theme support for selective refresh for widgets.
add_theme_support( 'customize-selective-refresh-widgets' );
// Add support for editor styles.
add_theme_support( 'editor-styles' );
// Enqueue editor styles.
add_editor_style( 'style-editor.css' );
add_editor_style( 'style-editor-extra.css' );
// Add support for responsive embedded content.
add_theme_support( 'responsive-embeds' );
// Remove support for block templates.
remove_theme_support( 'block-templates' );
}
endif;
add_action( 'after_setup_theme', 'vlr_setup' );
/**
* Register widget area.
*
* @link https://developer.wordpress.org/themes/functionality/sidebars/#registering-a-sidebar
*/
function vlr_widgets_init() {
register_sidebar(
array(
'name' => __( 'Footer', 'valier' ),
'id' => 'sidebar-1',
'description' => __( 'Add widgets here to appear in your footer.', 'valier' ),
'before_widget' => '<section id="%1$s" class="widget %2$s">',
'after_widget' => '</section>',
'before_title' => '<h2 class="widget-title">',
'after_title' => '</h2>',
)
);
}
add_action( 'widgets_init', 'vlr_widgets_init' );
/**
* Enqueue scripts and styles.
*/
function vlr_scripts() {
wp_enqueue_style( 'valier-style', get_stylesheet_uri(), array(), VLR_VERSION );
wp_enqueue_script( 'valier-script', get_template_directory_uri() . '/js/script.min.js', array(), VLR_VERSION, true );
if ( is_singular() && comments_open() && get_option( 'thread_comments' ) ) {
wp_enqueue_script( 'comment-reply' );
}
}
add_action( 'wp_enqueue_scripts', 'vlr_scripts' );
/**
* Enqueue the block editor script.
*/
function vlr_enqueue_block_editor_script() {
if ( is_admin() ) {
wp_enqueue_script(
'valier-editor',
get_template_directory_uri() . '/js/block-editor.min.js',
array(
'wp-blocks',
'wp-edit-post',
),
VLR_VERSION,
true
);
wp_add_inline_script( 'valier-editor', "tailwindTypographyClasses = '" . esc_attr( VLR_TYPOGRAPHY_CLASSES ) . "'.split(' ');", 'before' );
}
}
add_action( 'enqueue_block_assets', 'vlr_enqueue_block_editor_script' );
/**
* Add the Tailwind Typography classes to TinyMCE.
*
* @param array $settings TinyMCE settings.
* @return array
*/
function vlr_tinymce_add_class( $settings ) {
$settings['body_class'] = VLR_TYPOGRAPHY_CLASSES;
return $settings;
}
add_filter( 'tiny_mce_before_init', 'vlr_tinymce_add_class' );
/**
* Custom template tags for this theme.
*/
require get_template_directory() . '/inc/template-tags.php';
/**
* Functions which enhance the theme by hooking into WordPress.
*/
require get_template_directory() . '/inc/template-functions.php';

31
theme/header.php Normal file
View File

@@ -0,0 +1,31 @@
<?php
/**
* The header for our theme
*
* This is the template that displays the `head` element and everything up
* until the `#content` element.
*
* @link https://developer.wordpress.org/themes/basics/template-files/#template-partials
*
* @package Valier
*/
?><!doctype html>
<html <?php language_attributes(); ?>>
<head>
<meta charset="<?php bloginfo( 'charset' ); ?>">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="profile" href="https://gmpg.org/xfn/11">
<?php wp_head(); ?>
</head>
<body <?php body_class(); ?>>
<?php wp_body_open(); ?>
<div id="page">
<a href="#content" class="sr-only"><?php esc_html_e( 'Skip to content', 'valier' ); ?></a>
<?php get_template_part( 'template-parts/layout/header', 'content' ); ?>
<div id="content">

View File

@@ -0,0 +1,206 @@
<?php
/**
* Functions which enhance the theme by hooking into WordPress
*
* @package Valier
*/
/**
* Add a pingback url auto-discovery header for single posts, pages, or attachments.
*/
function vlr_pingback_header() {
if ( is_singular() && pings_open() ) {
printf( '<link rel="pingback" href="%s">', esc_url( get_bloginfo( 'pingback_url' ) ) );
}
}
add_action( 'wp_head', 'vlr_pingback_header' );
/**
* Changes comment form default fields.
*
* @param array $defaults The default comment form arguments.
*
* @return array Returns the modified fields.
*/
function vlr_comment_form_defaults( $defaults ) {
$comment_field = $defaults['comment_field'];
// Adjust height of comment form.
$defaults['comment_field'] = preg_replace( '/rows="\d+"/', 'rows="5"', $comment_field );
return $defaults;
}
add_filter( 'comment_form_defaults', 'vlr_comment_form_defaults' );
/**
* Filters the default archive titles.
*/
function vlr_get_the_archive_title() {
if ( is_category() ) {
$title = __( 'Category Archives: ', 'valier' ) . '<span>' . single_term_title( '', false ) . '</span>';
} elseif ( is_tag() ) {
$title = __( 'Tag Archives: ', 'valier' ) . '<span>' . single_term_title( '', false ) . '</span>';
} elseif ( is_author() ) {
$title = __( 'Author Archives: ', 'valier' ) . '<span>' . get_the_author_meta( 'display_name' ) . '</span>';
} elseif ( is_year() ) {
$title = __( 'Yearly Archives: ', 'valier' ) . '<span>' . get_the_date( _x( 'Y', 'yearly archives date format', 'valier' ) ) . '</span>';
} elseif ( is_month() ) {
$title = __( 'Monthly Archives: ', 'valier' ) . '<span>' . get_the_date( _x( 'F Y', 'monthly archives date format', 'valier' ) ) . '</span>';
} elseif ( is_day() ) {
$title = __( 'Daily Archives: ', 'valier' ) . '<span>' . get_the_date() . '</span>';
} elseif ( is_post_type_archive() ) {
$cpt = get_post_type_object( get_queried_object()->name );
$title = sprintf(
/* translators: %s: Post type singular name */
esc_html__( '%s Archives', 'valier' ),
$cpt->labels->singular_name
);
} elseif ( is_tax() ) {
$tax = get_taxonomy( get_queried_object()->taxonomy );
$title = sprintf(
/* translators: %s: Taxonomy singular name */
esc_html__( '%s Archives', 'valier' ),
$tax->labels->singular_name
);
} else {
$title = __( 'Archives:', 'valier' );
}
return $title;
}
add_filter( 'get_the_archive_title', 'vlr_get_the_archive_title' );
/**
* Determines whether the post thumbnail can be displayed.
*/
function vlr_can_show_post_thumbnail() {
return apply_filters( 'vlr_can_show_post_thumbnail', ! post_password_required() && ! is_attachment() && has_post_thumbnail() );
}
/**
* Returns the size for avatars used in the theme.
*/
function vlr_get_avatar_size() {
return 60;
}
/**
* Create the continue reading link
*
* @param string $more_string The string shown within the more link.
*/
function vlr_continue_reading_link( $more_string ) {
if ( ! is_admin() ) {
$continue_reading = sprintf(
/* translators: %s: Name of current post. */
wp_kses( __( 'Continue reading %s', 'valier' ), array( 'span' => array( 'class' => array() ) ) ),
the_title( '<span class="sr-only">"', '"</span>', false )
);
$more_string = '<a href="' . esc_url( get_permalink() ) . '">' . $continue_reading . '</a>';
}
return $more_string;
}
// Filter the excerpt more link.
add_filter( 'excerpt_more', 'vlr_continue_reading_link' );
// Filter the content more link.
add_filter( 'the_content_more_link', 'vlr_continue_reading_link' );
/**
* Outputs a comment in the HTML5 format.
*
* This function overrides the default WordPress comment output in HTML5
* format, adding the required class for Tailwind Typography. Based on the
* `html5_comment()` function from WordPress core.
*
* @param WP_Comment $comment Comment to display.
* @param array $args An array of arguments.
* @param int $depth Depth of the current comment.
*/
function vlr_html5_comment( $comment, $args, $depth ) {
$tag = ( 'div' === $args['style'] ) ? 'div' : 'li';
$commenter = wp_get_current_commenter();
$show_pending_links = ! empty( $commenter['comment_author'] );
if ( $commenter['comment_author_email'] ) {
$moderation_note = __( 'Your comment is awaiting moderation.', 'valier' );
} else {
$moderation_note = __( 'Your comment is awaiting moderation. This is a preview; your comment will be visible after it has been approved.', 'valier' );
}
?>
<<?php echo esc_attr( $tag ); ?> id="comment-<?php comment_ID(); ?>" <?php comment_class( $comment->has_children ? 'parent' : '', $comment ); ?>>
<article id="div-comment-<?php comment_ID(); ?>" class="comment-body">
<footer class="comment-meta">
<div class="comment-author vcard">
<?php
if ( 0 !== $args['avatar_size'] ) {
echo get_avatar( $comment, $args['avatar_size'] );
}
?>
<?php
$comment_author = get_comment_author_link( $comment );
if ( '0' === $comment->comment_approved && ! $show_pending_links ) {
$comment_author = get_comment_author( $comment );
}
printf(
/* translators: %s: Comment author link. */
wp_kses_post( __( '%s <span class="says">says:</span>', 'valier' ) ),
sprintf( '<b class="fn">%s</b>', wp_kses_post( $comment_author ) )
);
?>
</div><!-- .comment-author -->
<div class="comment-metadata">
<?php
printf(
'<a href="%s"><time datetime="%s">%s</time></a>',
esc_url( get_comment_link( $comment, $args ) ),
esc_attr( get_comment_time( 'c' ) ),
esc_html(
sprintf(
/* translators: 1: Comment date, 2: Comment time. */
__( '%1$s at %2$s', 'valier' ),
get_comment_date( '', $comment ),
get_comment_time()
)
)
);
edit_comment_link( __( 'Edit', 'valier' ), ' <span class="edit-link">', '</span>' );
?>
</div><!-- .comment-metadata -->
<?php if ( '0' === $comment->comment_approved ) : ?>
<em class="comment-awaiting-moderation"><?php echo esc_html( $moderation_note ); ?></em>
<?php endif; ?>
</footer><!-- .comment-meta -->
<div <?php vlr_content_class( 'comment-content' ); ?>>
<?php comment_text(); ?>
</div><!-- .comment-content -->
<?php
if ( '1' === $comment->comment_approved || $show_pending_links ) {
comment_reply_link(
array_merge(
$args,
array(
'add_below' => 'div-comment',
'depth' => $depth,
'max_depth' => $args['max_depth'],
'before' => '<div class="reply">',
'after' => '</div>',
)
)
);
}
?>
</article><!-- .comment-body -->
<?php
}

306
theme/inc/template-tags.php Normal file
View File

@@ -0,0 +1,306 @@
<?php
/**
* Custom template tags for this theme
*
* Eventually, some functionality here could be replaced by core features.
*
* @package Valier
*/
if ( ! function_exists( 'vlr_posted_on' ) ) :
/**
* Prints HTML with meta information for the current post-date/time.
*/
function vlr_posted_on() {
$time_string = '<time datetime="%1$s">%2$s</time>';
if ( get_the_time( 'U' ) !== get_the_modified_time( 'U' ) ) {
$time_string = '<time datetime="%1$s">%2$s</time><time datetime="%3$s">%4$s</time>';
}
$time_string = sprintf(
$time_string,
esc_attr( get_the_date( DATE_W3C ) ),
esc_html( get_the_date() ),
esc_attr( get_the_modified_date( DATE_W3C ) ),
esc_html( get_the_modified_date() )
);
printf(
'<a href="%1$s" rel="bookmark">%2$s</a>',
esc_url( get_permalink() ),
$time_string // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
);
}
endif;
if ( ! function_exists( 'vlr_posted_by' ) ) :
/**
* Prints HTML with meta information about theme author.
*/
function vlr_posted_by() {
printf(
/* translators: 1: posted by label, only visible to screen readers. 2: author link. 3: post author. */
'<span class="sr-only">%1$s</span><span class="author vcard"><a class="url fn n" href="%2$s">%3$s</a></span>',
esc_html__( 'Posted by', 'valier' ),
esc_url( get_author_posts_url( get_the_author_meta( 'ID' ) ) ),
esc_html( get_the_author() )
);
}
endif;
if ( ! function_exists( 'vlr_comment_count' ) ) :
/**
* Prints HTML with the comment count for the current post.
*/
function vlr_comment_count() {
if ( ! post_password_required() && ( comments_open() || get_comments_number() ) ) {
/* translators: %s: Name of current post. Only visible to screen readers. */
comments_popup_link( sprintf( __( 'Leave a comment<span class="sr-only"> on %s</span>', 'valier' ), get_the_title() ) );
}
}
endif;
if ( ! function_exists( 'vlr_entry_meta' ) ) :
/**
* Prints HTML with meta information for the categories, tags and comments.
* This template tag is used in the entry header.
*/
function vlr_entry_meta() {
// Hide author, post date, category and tag text for pages.
if ( 'post' === get_post_type() ) {
// Posted by.
vlr_posted_by();
// Posted on.
vlr_posted_on();
/* translators: used between list items, there is a space after the comma. */
$categories_list = get_the_category_list( __( ', ', 'valier' ) );
if ( $categories_list ) {
printf(
/* translators: 1: posted in label, only visible to screen readers. 2: list of categories. */
'<span class="sr-only">%1$s</span>%2$s',
esc_html__( 'Posted in', 'valier' ),
$categories_list // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
);
}
/* translators: used between list items, there is a space after the comma. */
$tags_list = get_the_tag_list( '', __( ', ', 'valier' ) );
if ( $tags_list ) {
printf(
/* translators: 1: tags label, only visible to screen readers. 2: list of tags. */
'<span class="sr-only">%1$s</span>%2$s',
esc_html__( 'Tags:', 'valier' ),
$tags_list // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
);
}
}
// Comment count.
if ( ! is_singular() ) {
vlr_comment_count();
}
// Edit post link.
edit_post_link(
sprintf(
wp_kses(
/* translators: %s: Name of current post. Only visible to screen readers. */
__( 'Edit <span class="sr-only">%s</span>', 'valier' ),
array(
'span' => array(
'class' => array(),
),
)
),
get_the_title()
)
);
}
endif;
if ( ! function_exists( 'vlr_entry_footer' ) ) :
/**
* Prints HTML with meta information for the categories, tags and comments.
*/
function vlr_entry_footer() {
// Hide author, post date, category and tag text for pages.
if ( 'post' === get_post_type() ) {
// Posted by.
vlr_posted_by();
// Posted on.
vlr_posted_on();
/* translators: used between list items, there is a space after the comma. */
$categories_list = get_the_category_list( __( ', ', 'valier' ) );
if ( $categories_list ) {
printf(
/* translators: 1: posted in label, only visible to screen readers. 2: list of categories. */
'<span class="sr-only">%1$s</span>%2$s',
esc_html__( 'Posted in', 'valier' ),
$categories_list // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
);
}
/* translators: used between list items, there is a space after the comma. */
$tags_list = get_the_tag_list( '', __( ', ', 'valier' ) );
if ( $tags_list ) {
printf(
/* translators: 1: tags label, only visible to screen readers. 2: list of tags. */
'<span class="sr-only">%1$s</span>%2$s',
esc_html__( 'Tags:', 'valier' ),
$tags_list // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
);
}
}
// Comment count.
if ( ! is_singular() ) {
vlr_comment_count();
}
// Edit post link.
edit_post_link(
sprintf(
wp_kses(
/* translators: %s: Name of current post. Only visible to screen readers. */
__( 'Edit <span class="sr-only">%s</span>', 'valier' ),
array(
'span' => array(
'class' => array(),
),
)
),
get_the_title()
)
);
}
endif;
if ( ! function_exists( 'vlr_post_thumbnail' ) ) :
/**
* Displays an optional post thumbnail, wrapping the post thumbnail in an
* anchor element except when viewing a single post.
*/
function vlr_post_thumbnail() {
if ( ! vlr_can_show_post_thumbnail() ) {
return;
}
if ( is_singular() ) :
?>
<figure>
<?php the_post_thumbnail(); ?>
</figure><!-- .post-thumbnail -->
<?php
else :
?>
<figure>
<a href="<?php the_permalink(); ?>" aria-hidden="true" tabindex="-1">
<?php the_post_thumbnail(); ?>
</a>
</figure>
<?php
endif; // End is_singular().
}
endif;
if ( ! function_exists( 'vlr_comment_avatar' ) ) :
/**
* Returns the HTML markup to generate a user avatar.
*
* @param mixed $id_or_email The Gravatar to retrieve. Accepts a user_id, gravatar md5 hash,
* user email, WP_User object, WP_Post object, or WP_Comment object.
*/
function vlr_get_user_avatar_markup( $id_or_email = null ) {
if ( ! isset( $id_or_email ) ) {
$id_or_email = get_current_user_id();
}
return sprintf( '<div class="vcard">%s</div>', get_avatar( $id_or_email, vlr_get_avatar_size() ) );
}
endif;
if ( ! function_exists( 'vlr_discussion_avatars_list' ) ) :
/**
* Displays a list of avatars involved in a discussion for a given post.
*
* @param array $comment_authors Comment authors to list as avatars.
*/
function vlr_discussion_avatars_list( $comment_authors ) {
if ( empty( $comment_authors ) ) {
return;
}
echo '<ol>', "\n";
foreach ( $comment_authors as $id_or_email ) {
printf(
"<li>%s</li>\n",
vlr_get_user_avatar_markup( $id_or_email ) // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
);
}
echo '</ol>', "\n";
}
endif;
if ( ! function_exists( 'vlr_the_posts_navigation' ) ) :
/**
* Wraps `the_posts_pagination` for use throughout the theme.
*/
function vlr_the_posts_navigation() {
the_posts_pagination(
array(
'mid_size' => 2,
'prev_text' => __( 'Newer posts', 'valier' ),
'next_text' => __( 'Older posts', 'valier' ),
)
);
}
endif;
if ( ! function_exists( 'vlr_content_class' ) ) :
/**
* Displays the class names for the post content wrapper.
*
* This allows us to add Tailwind Typographys modifier classes throughout
* the theme without repeating them in multiple files. (They can be edited
* at the top of the `../functions.php` file via the
* VLR_TYPOGRAPHY_CLASSES constant.)
*
* Based on WordPress cores `body_class` and `get_body_class` functions.
*
* @param string|string[] $classes Space-separated string or array of class
* names to add to the class list.
*/
function vlr_content_class( $classes = '' ) {
$all_classes = array( $classes, VLR_TYPOGRAPHY_CLASSES );
foreach ( $all_classes as &$class_groups ) {
if ( ! empty( $class_groups ) ) {
if ( ! is_array( $class_groups ) ) {
$class_groups = preg_split( '#\s+#', $class_groups );
}
} else {
// Ensure that we always coerce class to being an array.
$class_groups = array();
}
}
$combined_classes = array_merge( $all_classes[0], $all_classes[1] );
$combined_classes = array_map( 'esc_attr', $combined_classes );
// Separates class names with a single space, preparing them for the
// post content wrapper.
echo 'class="' . esc_attr( implode( ' ', $combined_classes ) ) . '"';
}
endif;

53
theme/index.php Normal file
View File

@@ -0,0 +1,53 @@
<?php
/**
* The main template file
*
* This is the most generic template file in a WordPress theme
* and one of the two required files for a theme (the other being style.css).
* It is used to display a page when nothing more specific matches a query.
* E.g., it puts together the home page when no `home.php` file exists.
*
* @link https://developer.wordpress.org/themes/basics/template-hierarchy/
*
* @package Valier
*/
get_header();
?>
<section id="primary">
<main id="main">
<?php
if ( have_posts() ) {
if ( is_home() && ! is_front_page() ) :
?>
<header class="entry-header">
<h1 class="entry-title"><?php single_post_title(); ?></h1>
</header><!-- .entry-header -->
<?php
endif;
// Load posts loop.
while ( have_posts() ) {
the_post();
get_template_part( 'template-parts/content/content' );
}
// Previous/next page navigation.
vlr_the_posts_navigation();
} else {
// If no content, include the "No posts found" template.
get_template_part( 'template-parts/content/content', 'none' );
}
?>
</main><!-- #main -->
</section><!-- #primary -->
<?php
get_footer();

11
theme/js/readme.txt Normal file
View File

@@ -0,0 +1,11 @@
The three JavaScript files at `../../javascript` will be processed by esbuild,
and the output files will be created in this folder with `.min.js` extensions.
The files `script.min.js`, `block-editor.min.js` and
`tailwind-typography-classes.js` are enqueued by default in `../functions.php`.
If you would like to add new files to be processed by esbuild, add them to the
`../../javascript` folder and then add them to the `development:esbuild` key in
your `package.json` file.
DO NOT directly edit `*.min.js` files, as these files are ignored by git and
will be overwritten the next time esbuild runs.

View File

@@ -0,0 +1,7 @@
Place your themes language files in this directory.
Please visit the following links to learn more about translating WordPress themes:
https://make.wordpress.org/polyglots/teams/
https://developer.wordpress.org/themes/functionality/localization/
https://developer.wordpress.org/reference/functions/load_theme_textdomain/

41
theme/page.php Normal file
View File

@@ -0,0 +1,41 @@
<?php
/**
* The template for displaying all pages
*
* This is the template that displays all pages by default. Please note that
* this is the WordPress construct of pages: specifically, posts with a post
* type of `page`.
*
* @link https://developer.wordpress.org/themes/basics/template-hierarchy/
*
* @package Valier
*/
get_header();
?>
<section id="primary">
<main id="main">
<?php
/* Start the Loop */
while ( have_posts() ) :
the_post();
get_template_part( 'template-parts/content/content', 'page' );
// If comments are open, or we have at least one comment, load
// the comment template.
if ( comments_open() || get_comments_number() ) {
comments_template();
}
endwhile; // End of the loop.
?>
</main><!-- #main -->
</section><!-- #primary -->
<?php
get_footer();

BIN
theme/screenshot.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 264 B

52
theme/search.php Normal file
View File

@@ -0,0 +1,52 @@
<?php
/**
* The template for displaying search results pages
*
* @link https://developer.wordpress.org/themes/basics/template-hierarchy/#search-result
*
* @package Valier
*/
get_header();
?>
<section id="primary">
<main id="main">
<?php if ( have_posts() ) : ?>
<header class="page-header">
<?php
printf(
/* translators: 1: search result title. 2: search term. */
'<h1 class="page-title">%1$s <span>%2$s</span></h1>',
esc_html__( 'Search results for:', 'valier' ),
get_search_query()
);
?>
</header><!-- .page-header -->
<?php
// Start the Loop.
while ( have_posts() ) :
the_post();
get_template_part( 'template-parts/content/content', 'excerpt' );
// End the loop.
endwhile;
// Previous/next page navigation.
vlr_the_posts_navigation();
else :
// If no content is found, get the `content-none` template part.
get_template_part( 'template-parts/content/content', 'none' );
endif;
?>
</main><!-- #main -->
</section><!-- #primary -->
<?php
get_footer();

50
theme/single.php Normal file
View File

@@ -0,0 +1,50 @@
<?php
/**
* The template for displaying all single posts
*
* @link https://developer.wordpress.org/themes/basics/template-hierarchy/#single-post
*
* @package Valier
*/
get_header();
?>
<section id="primary">
<main id="main">
<?php
/* Start the Loop */
while ( have_posts() ) :
the_post();
get_template_part( 'template-parts/content/content', 'single' );
if ( is_singular( 'post' ) ) {
// Previous/next post navigation.
the_post_navigation(
array(
'next_text' => '<span aria-hidden="true">' . __( 'Next Post', 'valier' ) . '</span> ' .
'<span class="sr-only">' . __( 'Next post:', 'valier' ) . '</span> <br/>' .
'<span>%title</span>',
'prev_text' => '<span aria-hidden="true">' . __( 'Previous Post', 'valier' ) . '</span> ' .
'<span class="sr-only">' . __( 'Previous post:', 'valier' ) . '</span> <br/>' .
'<span>%title</span>',
)
);
}
// If comments are open, or we have at least one comment, load
// the comment template.
if ( comments_open() || get_comments_number() ) {
comments_template();
}
// End the loop.
endwhile;
?>
</main><!-- #main -->
</section><!-- #primary -->
<?php
get_footer();

View File

@@ -0,0 +1,33 @@
<?php
/**
* Template part for displaying post archives and search results
*
* @link https://developer.wordpress.org/themes/basics/template-hierarchy/
*
* @package Valier
*/
?>
<article id="post-<?php the_ID(); ?>" <?php post_class(); ?>>
<header class="entry-header">
<?php
if ( is_sticky() && is_home() && ! is_paged() ) {
printf( '%s', esc_html_x( 'Featured', 'post', 'valier' ) );
}
the_title( sprintf( '<h2 class="entry-title"><a href="%s" rel="bookmark">', esc_url( get_permalink() ) ), '</a></h2>' );
?>
</header><!-- .entry-header -->
<?php vlr_post_thumbnail(); ?>
<div <?php vlr_content_class( 'entry-content' ); ?>>
<?php the_excerpt(); ?>
</div><!-- .entry-content -->
<footer class="entry-footer">
<?php vlr_entry_footer(); ?>
</footer><!-- .entry-footer -->
</article><!-- #post-${ID} -->

View File

@@ -0,0 +1,76 @@
<?php
/**
* Template part for displaying a message when posts are not found
*
* @link https://developer.wordpress.org/themes/basics/template-hierarchy/
*
* @package Valier
*/
?>
<section>
<header class="page-header">
<?php if ( is_search() ) : ?>
<h1 class="page-title">
<?php
printf(
/* translators: 1: search result title. 2: search term. */
'<h1 class="page-title">%1$s <span>%2$s</span></h1>',
esc_html__( 'Search results for:', 'valier' ),
get_search_query()
);
?>
</h1>
<?php else : ?>
<h1 class="page-title"><?php esc_html_e( 'Nothing Found', 'valier' ); ?></h1>
<?php endif; ?>
</header><!-- .page-header -->
<div <?php vlr_content_class( 'page-content' ); ?>>
<?php
if ( is_home() && current_user_can( 'publish_posts' ) ) :
?>
<p>
<?php esc_html_e( 'Your site is set to show the most recent posts on your homepage, but you haven&rsquo;t published any posts.', 'valier' ); ?>
</p>
<p>
<a href="<?php echo esc_url( admin_url( 'edit.php' ) ); ?>">
<?php
/* translators: 1: link to WP admin new post page. */
esc_html_e( 'Add or publish posts', 'valier' );
?>
</a>
</p>
<?php
elseif ( is_search() ) :
?>
<p>
<?php esc_html_e( 'Your search generated no results. Please try a different search.', 'valier' ); ?>
</p>
<?php
get_search_form();
else :
?>
<p>
<?php esc_html_e( 'No content matched your request.', 'valier' ); ?>
</p>
<?php
get_search_form();
endif;
?>
</div><!-- .page-content -->
</section>

View File

@@ -0,0 +1,60 @@
<?php
/**
* Template part for displaying pages
*
* @link https://developer.wordpress.org/themes/basics/template-hierarchy/
*
* @package Valier
*/
?>
<article id="post-<?php the_ID(); ?>" <?php post_class(); ?>>
<header class="entry-header">
<?php
if ( ! is_front_page() ) {
the_title( '<h1 class="entry-title">', '</h1>' );
} else {
the_title( '<h2 class="entry-title">', '</h2>' );
}
?>
</header><!-- .entry-header -->
<?php vlr_post_thumbnail(); ?>
<div <?php vlr_content_class( 'entry-content' ); ?>>
<?php
the_content();
wp_link_pages(
array(
'before' => '<div>' . __( 'Pages:', 'valier' ),
'after' => '</div>',
)
);
?>
</div><!-- .entry-content -->
<?php if ( get_edit_post_link() ) : ?>
<footer class="entry-footer">
<?php
edit_post_link(
sprintf(
wp_kses(
/* translators: %s: Name of current post. Only visible to screen readers. */
__( 'Edit <span class="sr-only">%s</span>', 'valier' ),
array(
'span' => array(
'class' => array(),
),
)
),
get_the_title()
)
);
?>
</footer><!-- .entry-footer -->
<?php endif; ?>
</article><!-- #post-<?php the_ID(); ?> -->

View File

@@ -0,0 +1,56 @@
<?php
/**
* Template part for displaying single posts
*
* @link https://developer.wordpress.org/themes/basics/template-hierarchy/
*
* @package Valier
*/
?>
<article id="post-<?php the_ID(); ?>" <?php post_class(); ?>>
<header class="entry-header">
<?php the_title( '<h1 class="entry-title">', '</h1>' ); ?>
<?php if ( ! is_page() ) : ?>
<div class="entry-meta">
<?php vlr_entry_meta(); ?>
</div><!-- .entry-meta -->
<?php endif; ?>
</header><!-- .entry-header -->
<?php vlr_post_thumbnail(); ?>
<div <?php vlr_content_class( 'entry-content' ); ?>>
<?php
the_content(
sprintf(
wp_kses(
/* translators: %s: Name of current post. Only visible to screen readers. */
__( 'Continue reading<span class="sr-only"> "%s"</span>', 'valier' ),
array(
'span' => array(
'class' => array(),
),
)
),
get_the_title()
)
);
wp_link_pages(
array(
'before' => '<div>' . __( 'Pages:', 'valier' ),
'after' => '</div>',
)
);
?>
</div><!-- .entry-content -->
<footer class="entry-footer">
<?php vlr_entry_footer(); ?>
</footer><!-- .entry-footer -->
</article><!-- #post-${ID} -->

View File

@@ -0,0 +1,46 @@
<?php
/**
* Template part for displaying posts
*
* @link https://developer.wordpress.org/themes/basics/template-hierarchy/
*
* @package Valier
*/
?>
<article id="post-<?php the_ID(); ?>" <?php post_class(); ?>>
<header class="entry-header">
<?php
if ( is_sticky() && is_home() && ! is_paged() ) {
printf( '<span">%s</span>', esc_html_x( 'Featured', 'post', 'valier' ) );
}
if ( is_singular() ) :
the_title( '<h1 class="entry-title">', '</h1>' );
else :
the_title( sprintf( '<h2 class="entry-title"><a href="%s" rel="bookmark">', esc_url( get_permalink() ) ), '</a></h2>' );
endif;
?>
</header><!-- .entry-header -->
<?php vlr_post_thumbnail(); ?>
<div <?php vlr_content_class( 'entry-content' ); ?>>
<?php
the_content();
wp_link_pages(
array(
'before' => '<div>' . __( 'Pages:', 'valier' ),
'after' => '</div>',
)
);
?>
</div><!-- .entry-content -->
<footer class="entry-footer">
<?php vlr_entry_footer(); ?>
</footer><!-- .entry-footer -->
</article><!-- #post-${ID} -->

View File

@@ -0,0 +1,52 @@
<?php
/**
* Template part for displaying the footer content
*
* @link https://developer.wordpress.org/themes/basics/template-hierarchy/
*
* @package Valier
*/
?>
<footer id="colophon">
<?php if ( is_active_sidebar( 'sidebar-1' ) ) : ?>
<aside role="complementary" aria-label="<?php esc_attr_e( 'Footer', 'valier' ); ?>">
<?php dynamic_sidebar( 'sidebar-1' ); ?>
</aside>
<?php endif; ?>
<?php if ( has_nav_menu( 'menu-2' ) ) : ?>
<nav aria-label="<?php esc_attr_e( 'Footer Menu', 'valier' ); ?>">
<?php
wp_nav_menu(
array(
'theme_location' => 'menu-2',
'menu_class' => 'footer-menu',
'depth' => 1,
)
);
?>
</nav>
<?php endif; ?>
<div>
<?php
$vlr_blog_info = get_bloginfo( 'name' );
if ( ! empty( $vlr_blog_info ) ) :
?>
<a href="<?php echo esc_url( home_url( '/' ) ); ?>" rel="home"><?php bloginfo( 'name' ); ?></a>,
<?php
endif;
/* translators: 1: WordPress link, 2: WordPress. */
printf(
'<a href="%1$s">proudly powered by %2$s</a>.',
esc_url( __( 'https://wordpress.org/', 'valier' ) ),
'WordPress'
);
?>
</div>
</footer><!-- #colophon -->

View File

@@ -0,0 +1,47 @@
<?php
/**
* Template part for displaying the header content
*
* @link https://developer.wordpress.org/themes/basics/template-hierarchy/
*
* @package Valier
*/
?>
<header id="masthead">
<div>
<?php
if ( is_front_page() ) :
?>
<h1><?php bloginfo( 'name' ); ?></h1>
<?php
else :
?>
<p><a href="<?php echo esc_url( home_url( '/' ) ); ?>" rel="home"><?php bloginfo( 'name' ); ?></a></p>
<?php
endif;
$vlr_description = get_bloginfo( 'description', 'display' );
if ( $vlr_description || is_customize_preview() ) :
?>
<p><?php echo $vlr_description; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?></p>
<?php endif; ?>
</div>
<nav id="site-navigation" aria-label="<?php esc_attr_e( 'Main Navigation', 'valier' ); ?>">
<button aria-controls="primary-menu" aria-expanded="false"><?php esc_html_e( 'Primary Menu', 'valier' ); ?></button>
<?php
wp_nav_menu(
array(
'theme_location' => 'menu-1',
'menu_id' => 'primary-menu',
'items_wrap' => '<ul id="%1$s" class="%2$s" aria-label="submenu">%3$s</ul>',
)
);
?>
</nav><!-- #site-navigation -->
</header><!-- #masthead -->

39
theme/theme.json Normal file
View File

@@ -0,0 +1,39 @@
{
"$schema": "https://schemas.wp.org/trunk/theme.json",
"version": 2,
"settings": {
"color": {
"palette": [
{
"slug": "background",
"color": "#ffffff",
"name": "Background"
},
{
"slug": "foreground",
"color": "#404040",
"name": "Foreground"
},
{
"slug": "primary",
"color": "#b91c1c",
"name": "Primary"
},
{
"slug": "secondary",
"color": "#15803d",
"name": "Secondary"
},
{
"slug": "tertiary",
"color": "#0369a1",
"name": "Tertiary"
}
]
},
"layout": {
"contentSize": "40rem",
"wideSize": "60rem"
}
}
}