Tag Archive : php

/ php

code coder coding

I’m still new to WordPress development put plugging along at a good pace. We recently started developing our business toward online marketing and web development, which has pushed me into this domain. In out custom themes we want the ability to add specific meta tags to the page header for SEO.

There are actually paid plugins that do exactly this. In my case I’m building it into a custom theme, but it could easily be a standalone plugin you could drop into any project.

This is what I’ve got so far…

In my themes functions.php I’ve created a new class to wrap all the functions necessary.

abstract class MyTheme_Meta_Box
{
....
}

I’ve then defined a array of meta tags we want to be available on a per post basis.

....
private static $fields = [
        // Search Engine
        "name=description",
        "name=image",
        // Schema.org for Google
        "itemprop=name",
        "itemprop=description",
        "itemprop=image",
        //  Twitter
        "name=twitter:card",
        "name=twitter:title",
        "name=twitter:description",
        "name=twitter:image:src",
        // Open Graph general (Facebook, Pinterest & Google+)
        "name=og:title",
        "name=og:description",
        "name=og:image",
        "name=og:url",
        "name=og:site_name",
        "name=og:locale",
        "name=og:type",
    ];
....

The next step was to define the function to add the metabox to the page editor and define the html.

    public static function add()
    {
        $pagetypes = ['post', 'page'];
        foreach ($pagetypes as $pagetype) {
            add_meta_box(
                'MyTheme_box_id',        
                'Custom Meta Data',      
                [self::class, 'html'],   
                $pagetype                
            );
        }
    }

    public static function html($post)
    {
        foreach (self::$fields as $field) {
            $value = get_post_meta($post->ID, $field, true);
            ?>
            <label for="<?php echo $field ?>"><?php echo $field ?></label>
            <input name="<?php echo $field ?>" id="<?php echo $field ?>" value="<?php echo $value ?>" style="width: 100%">
            <br>
        <?php
        }
    }

At this point we could register the function, but we’ll save that for the end and add them all at once. We also need to add a function to handle saving the new data to the database.

The official documentation has multiple ways of doing this, but recommends using the update function as such:

    public static function save($post_id)
    {
        foreach (self::$fields as $field) {
            if (array_key_exists($field, $_POST)) {
                update_post_meta(
                    $post_id,
                    $field,
                    $_POST[$field]
                );
            }
        }
    }

With that, all the data is saved. Looking at it now, I should probably put in a step to remove empty tags from the database. Mental note for later.

We now need a function to pull and display that data, which can be hooked into wp_head.

public static function head()
    {
        foreach (self::$fields as $field) {
            // get meta key
            $value = get_post_meta(get_queried_object_id(), $field, true);

            //Output
            if (!empty($value)) {
                printf(
                    '<meta %s content="%s" />',
                    esc_attr((trim($field))),
                    esc_attr((trim($value)))
                );
            }
        }
    }

The only thing left to do is register the functions on the appropriate hooks. This we do outside of the class, if there is any confusion.

add_action('add_meta_boxes', ['MyTheme_Meta_Box', 'add']);
add_action('save_post', ['MyTheme_Meta_Box', 'save']);
add_action('wp_head', ['MyTheme_Meta_Box', 'head']);

That’s it, all the meta fields will now be displayed in the header if they aren’t empty.

A minimal WordPress Theme

July 20, 2019 | Coding | No Comments

WordPress Logo

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