A minimal WordPress Theme
July 20, 2019 | Coding | No Comments

The company I work for is growing, and part of that growth has me learning WordPress. Id honestly rather not touch it, I do not enjoy working in PHP. But there it is anyway.
I was quickly surprised at how simple, and how little you need to make a theme. You only need two files: index.php and style.css. So I decided to make one that was that simple to demonstrate here.
Shortly into it I decided to add a menu and a sidebar, so two more files: functions.php and sidebar.php. How functional is a theme really, if you don’t have a customizable menu or widget area?
All the code is below, comments inline and github repo is available.
style.css
/* Theme Name: Minimal WordPress Theme URI: https://wordpress.org/themes/twentyseventeen/ Author: the WordPress team Author URI: https://wordpress.org/ Description: Minimal WordPress brings your site to life with immersive featured images and subtle animations. With a focus on business sites, it features multiple sections on the front page as well as widgets, navigation and social menus, a logo, and more. Personalize its asymmetrical grid with a custom color scheme and showcase your multimedia content with post formats. Our default theme for 2017 works great in many languages, for any abilities, and on any device. Version: 1.0 License: GNU General Public License v2 or later License URI: http://www.gnu.org/licenses/gpl-2.0.html Text Domain: minimaltheme Tags: one-column, two-columns, right-sidebar, flexible-header, accessibility-ready, custom-colors, custom-header, custom-menu, custom-logo, editor-style, featured-images, footer-widgets, post-formats, rtl-language-support, sticky-post, theme-options, threaded-comments, translation-ready This theme, like WordPress, is licensed under the GPL. Use it to make something cool, have fun, and share what you've learned with others. */
index.php
<?php /* Everything is going to be displayed on this one page, we don't want to put potentially thousands of posts on our one page... so we redefine the query to paginate. But only if we are not on a single item page. */ if (!is_singular()) { $paged = (get_query_var('paged')) ? get_query_var('paged') : '1'; $args = array( 'nopaging' => false, 'paged' => $paged, 'posts_per_page' => '2', 'post_type' => 'post', ); $query = new WP_Query($args); } else { $query = $wp_query; } ?> <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>My Theme</title> <!-- wp_head will inject all of wordpress's specific header info and anything else we define, like custome css. We could just write that in here ourselves, but we could end up with mulitple headers and this helps keep us DRY --> <?php wp_head() ?> </head> <body> <nav> <div class="nav-wrapper container"> <a href="/" class="brand-logo"><?php echo get_bloginfo('name'); ?></a> <?php wp_nav_menu(array( 'theme_location' => 'main-menu', 'container_class' => 'right' )); ?> </div> </nav> <main class="container"> <div class="row"> <div class="col s12 m8"> <?php if ($query->have_posts()) : while ($query->have_posts()) : $query->the_post(); ?> <article class="card-panel"> <h3> <a href="<?php the_permalink(); ?>" rel="bookmark" title="Permanent Link to <?php the_title_attribute(); ?>"><?php the_title(); ?></a> </h3> <small><?php the_time('F jS, Y'); ?> by <?php the_author(); ?></small> <div class="entry"> <!-- we only want to show the full post if we aren't on a list --> <?php if (is_singular()) { the_content(); // If comments are open or we have at least one comment, // load up the comment template. if (comments_open() || get_comments_number()) { comments_template(); } } else { the_excerpt(); } ?> </div> <p class="postmetadata"><?php _e('Posted in'); ?> <?php the_category(', '); ?></p> </article> <?php endwhile; // show pagination links echo paginate_links(array( 'total' => $query->max_num_pages, 'mid_size' => 2 )); else : ?> <p><?php esc_html_e('Sorry, no posts matched your criteria.'); ?></p> <?php endif; ?> </div> <div class="col s12 m4"> <?php get_sidebar() ?> </div> </div> </main> <footer> <!-- like wp_head wp_footer injects necessary script stuff such as the code that gives us the WordPress Admin bar --> <?php wp_footer(); ?> </footer> </body> </html>
functions.php
<?php /* You can register your stylesheets and scripts in the same function but I prefer to keep them seperate, it just feels cleaner to me */ function minimaltheme_enqueue_styles() { wp_enqueue_style('materialize-css', "https://cdnjs.cloudflare.com/ajax/libs/materialize/1.0.0/css/materialize.min.css"); } add_action('wp_enqueue_scripts', 'minimaltheme_enqueue_styles'); function minimaltheme_enqueue_scripts() { wp_enqueue_script('materialize-js', "https://cdnjs.cloudflare.com/ajax/libs/materialize/1.0.0/js/materialize.min.js"); } add_action('wp_enqueue_scripts', 'minimaltheme_enqueue_scripts'); wp_enqueue_style('style', get_stylesheet_uri()); /* We need one menu for our nav bar, but you can register as many as you like and put them anywhere */ function register_menus() { register_nav_menu('main-menu', __('Main Menu')); } add_action('init', 'register_menus'); // register a sidebar to user throughout the site add_action('widgets_init', 'minimaltheme_register_sidebars'); function minimaltheme_register_sidebars() { register_sidebar(array( 'name' => __('Main Sidebar', 'minimaltheme'), 'id' => 'sidebar', 'description' => __('Widgets in this area will be shown on all posts and pages.', 'minimaltheme'), 'before_widget' => '<div class="card"><div class="card-content">', 'after_widget' => '</div></div>', 'before_title' => '<div class="card-title">', 'after_title' => '</div>', )); }
sidebar.php
<?php if (!is_active_sidebar('sidebar')) { return; } dynamic_sidebar('sidebar');
Available at https://github.com/wsimmerson/minimaltheme
php, WordPress