【WordPress ソースコード】中級編:ブログサイト/2カラム

目次

テーマディレクトリ構成

    
blog
 ├─img
 │  ├─common
 │  │  ├─favicon.ico
 │  │  ├─logo.svg
 │  │  └─search.png
 │  │
 │  └─sidebar
 │     └─author.jpg
 │
 ├─404.php
 ├─category.php
 ├─date.php
 ├─footer.php
 ├─functions.php
 ├─header.php
 ├─index.php
 ├─loop.php
 ├─page.php
 ├─search.php
 ├─searchform.php
 ├─sidebar.php
 ├─single.php
 └─style.css
    
  

404.php

別タブで開く
404.php

<?php
  wp_safe_redirect(home_url(), 301);
  exit;
?>

category.php

別タブで開く
category.php

<?php get_header(); ?>

<div id="container" class="wrapper">
  <main>
    <?php
      $cat = get_the_category();
      $catname = $cat[0]->cat_name;
    ?>
    <h1 class="page-title"><?php echo $catname; ?>一覧</h1>

    <?php
      if (have_posts()):
        get_template_part('loop');

        if (function_exists("pagination")) {
          pagination($wp_query->max_num_pages);
        }
      endif;
    ?>
  </main>

  <?php get_sidebar(); ?>
</div>

<?php get_footer(); ?>

date.php

別タブで開く
date.php

<?php get_header(); ?>

<div id="container" class="wrapper">
  <main>
    <h1 class="page-title">
      <?php echo get_query_var('year').'年'.get_query_var('monthnum').'月'; ?>
    </h1>

    <?php
      if (have_posts()):
        get_template_part('loop');

        if (function_exists("pagination")) {
          pagination($wp_query->max_num_pages);
        }
      endif;
    ?>
  </main>

  <?php get_sidebar(); ?>
</div>

<?php get_footer(); ?>

別タブで開く
footer.php

  <footer id="footer">
    <div class="content wrapper">
      <section class="item">
        <h3 class="footer-title">About</h3>
        <p>
          テキストテキストテキストテキストテキストテキストテキストテキストテキストテキスト
          テキストテキストテキストテキストテキストテキストテキストテキストテキストテキスト
          テキストテキストテキストテキストテキストテキストテキストテキストテキストテキスト
        </p>
        <ul class="about-list">
          <li><a href="<?php echo esc_url(home_url('/profile/')); ?>" class="arrow">プロフィール詳細</a></li>
          <li><a href="<?php echo esc_url(home_url('/contact/')); ?>" class="arrow">お問い合わせ</a></li>
        </ul>
      </section>

      <section class="item">
        <h3 class="footer-title">Menu</h3>
        <ul class="menu-list">
          <li><a href="<?php echo esc_url(home_url('/category/news/')); ?>">NEWS</a></li>
          <li><a href="<?php echo esc_url(home_url('/category/column/')); ?>">COLUMN</a></li>
          <li><a href="<?php echo esc_url(home_url('/category/hotel/')); ?>">HOTEL</a></li>
        </ul>
      </section>

      <section class="item">
        <h3 class="footer-title">Twitter</h3>
        <a class="twitter-timeline" data-height="315" href="https://twitter.com/TwitterJP?ref_src=twsrc%5Etfw">Tweets by TwitterJP</a>
        <script async src="https://platform.twitter.com/widgets.js"></script>
      </section>
    </div>

    <p class="copyright">&copy; Travel Blog</p>
  </footer>

  <?php wp_footer(); ?>
</body>
</html>

functions.php

別タブで開く
functions.php

<?php

/**************************************************
CSSファイルの読み込み
**************************************************/
function my_enqueue_styles() {
  wp_enqueue_style('ress', '//unpkg.com/ress/dist/ress.min.css', array(), false, 'all');
  wp_enqueue_style('style', get_stylesheet_uri(), array('ress'), false, 'all');
}
add_action('wp_enqueue_scripts', 'my_enqueue_styles');

/**************************************************
アイキャッチを有効化
**************************************************/
add_theme_support('post-thumbnails');

/**************************************************
ページネーション
**************************************************/
function pagination($pages = '', $range = 2) {
  $showitems = ($range * 2) + 1;

  global $paged;
  if(empty($paged)) {
    $paged = 1;
  }

  if($pages == '') {
    global $wp_query;
    $pages = $wp_query->max_num_pages;
    if(!$pages) {
      $pages = 1;
    }
  }

  if(1 != $pages) {
    echo '<div class="pagination">';
    echo '<ul>';
    if($paged > 1) {
      echo '<li class="prev"><a href="' . esc_url(get_pagenum_link($paged - 1)) . '">前のページ</a></li>';
    }

    for ($i=1; $i <= $pages; $i++) {
      if (1 != $pages &&(!($i >= $paged+$range+1 || $i <= $paged-$range-1) || $pages <= $showitems )) {
        if ($paged == $i) {
          echo '<li class="active">' .$i. '</li>';
        } else {
          echo '<li><a href="' . esc_url(get_pagenum_link($i)) . '">' .$i. '</a></li>';
        }
      }
    }

    if ($paged < $pages) {
      echo '<li class="next"><a href="' . esc_url(get_pagenum_link($paged + 1)) . '">次のページ</a></li>';
    }
    echo '</ul>';
    echo '</div>';
  }
}

/**************************************************
サイドバーウィジェット
**************************************************/
if (function_exists('register_sidebar')) {
  register_sidebar(array(
    'name' => 'サイドバー',
    'id' => 'sidebar',
    'description' => 'サイドバーウィジェット',
    'before_widget' => '<div>',
    'after_widget' => '</div>',
    'before_title' => '<h3 class="side-title">',
    'after_title' => '</h3>'
 ));
}

/**************************************************
サイト内検索の対象を「投稿」のみにする
**************************************************/
function search_filter($query) {
  if ($query -> is_search) {
    $query -> set('post_type', 'post');
  }
  return $query;
}
add_filter('pre_get_posts', 'search_filter');

header.php

別タブで開く
header.php

<!DOCTYPE html>
<html lang="ja">
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <title><?php echo bloginfo('name'); ?></title>
  <meta name="description" content="<?php bloginfo('description'); ?>">
  <link rel="icon" href="<?php echo esc_url(get_theme_file_uri('img/common/favicon.ico')); ?>">

  <?php wp_head(); ?>
</head>

<body>
  <header id="header">
    <?php $html_tag = (is_home() || is_front_page()) ? 'h1' : 'div'; ?>
    <<?php echo $html_tag; ?> class="site-title wrapper">
      <a href="<?php echo esc_url(home_url()); ?>">
        <img src="<?php echo esc_url(get_theme_file_uri('img/common/logo.svg')); ?>" alt="Travel Blog">
      </a>
    </<?php echo $html_tag; ?>>

    <nav id="navi">
      <ul class="wrapper">
        <li><a href="<?php echo esc_url(home_url('/category/news/')); ?>">NEWS</a></li>
        <li><a href="<?php echo esc_url(home_url('/category/column/')); ?>">COLUMN</a></li>
        <li><a href="<?php echo esc_url(home_url('/category/hotel/')); ?>">HOTEL</a></li>
        <li><a href="<?php echo esc_url(home_url('/contact/')); ?>">CONTACT</a></li>
      </ul>
    </nav>
  </header>

index.php

別タブで開く
index.php

<?php get_header(); ?>

<div id="container" class="wrapper">
  <main>
    <?php
      if (have_posts()):
        get_template_part('loop');

        if (function_exists("pagination")) {
          pagination($wp_query->max_num_pages);
        }
      endif;
    ?>
  </main>

  <?php get_sidebar(); ?>
</div>

<?php get_footer(); ?>

loop.php

別タブで開く
loop.php

<?php while(have_posts()):the_post(); ?>
  <article>
    <h2 class="article-title">
      <a href="<?php the_permalink(); ?>"><?php the_title() ?></a>
    </h2>
    <ul class="meta">
      <li><?php the_time('Y/m/d'); ?></li>
      <?php if(!is_category()) { ?>
        <?php
          $cat = get_the_category();
          $catname = $cat[0]->cat_name;
        ?>
        <li><?php echo $catname; ?></li>
      <?php } ?>
    </ul>
    <a href="<?php the_permalink(); ?>"><?php the_post_thumbnail(); ?></a>
    <div class="text">
      <?php
        if (mb_strlen(strip_tags(get_the_content()), 'UTF-8') > 80) {
          $content = mb_substr(strip_tags(get_the_content()), 0, 80, 'UTF-8');
          echo $content . '…';
        } else {
          echo strip_tags(get_the_content());
        }
      ?>
    </div>
    <div class="readmore"><a href="<?php the_permalink(); ?>">READ MORE</a></div>
  </article>
<?php endwhile; ?>

page.php

別タブで開く
page.php

<?php get_header(); ?>

<div id="container" class="wrapper">
  <main>
    <?php if(have_posts()):while(have_posts()):the_post(); ?>
      <article>
        <h1 class="article-title"><?php the_title() ?></h1>
        <?php the_post_thumbnail(); ?>
        <div class="text"><?php the_content(); ?></div>
      </article>
    <?php endwhile;endif; ?>
  </main>

  <?php get_sidebar(); ?>
</div>

<?php get_footer(); ?>

別タブで開く
search.php

<?php get_header(); ?>

<div id="container" class="wrapper">
  <main>
    <?php if (have_posts()): ?>
      <?php if (!$_GET['s']) { ?>
        <p>検索キーワードが未入力です<p>

      <?php } else { ?>
        <h1 class="page-title">
          「<?php echo esc_html($_GET['s']); ?>」の検索結果:<?php echo $wp_query->found_posts; ?>件
        </h1>

        <?php
          get_template_part('loop');

          if (function_exists("pagination")) {
            pagination($wp_query->max_num_pages);
          }
        ?>
      <?php } ?>
    <?php else: ?>
      <p>検索されたキーワードに一致する記事はありませんでした</p>

    <?php endif; ?>
  </main>

  <?php get_sidebar(); ?>
</div>

<?php get_footer(); ?>

searchform.php

別タブで開く
searchform.php

<form method="get" id="searchform" action="<?php echo esc_url(home_url()); ?>">
  <input type="text" name="s" id="s" placeholder="キーワードで検索する">
  <button type="submit">
    <img src="<?php echo esc_url(get_theme_file_uri('img/common/search.png')); ?>" alt="">
  </button>
</form>

sidebar.php

別タブで開く
sidebar.php

<aside id="sidebar">
  <section class="author">
    <img src="<?php echo esc_url(get_theme_file_uri('img/sidebar/author.jpg')); ?>" alt="テキストテキストテキスト">
    <h3 class="side-title">Name Name</h3>
    <p class="profile">
      プロフィールテキストテキストテキストテキストテキストテキストテキスト
      テキストテキストテキストテキストテキストテキストテキストテキストテキスト
      テキストテキストテキストテキストテキストテキストテキストテキストテキスト
    </p>
  </section>

  <?php get_search_form(); ?>

  <section class="archive">
    <?php dynamic_sidebar('sidebar'); ?>
  </section>
</aside>

single.php

別タブで開く
single.php

<?php get_header(); ?>

<div id="container" class="wrapper">
  <main>
    <?php if(have_posts()):while(have_posts()):the_post(); ?>
      <?php
        $cat = get_the_category();
        $catname = $cat[0]->cat_name;
      ?>
      <article>
        <h1 class="article-title">
          <a href="<?php the_permalink(); ?>"><?php the_title() ?></a>
        </h1>
        <ul class="meta">
          <li><?php the_time('Y/m/d'); ?></li>
          <li><?php echo $catname; ?></li>
        </ul>
        <a href="<?php the_permalink(); ?>"><?php the_post_thumbnail(); ?></a>
        <div class="text"><?php the_content(); ?></div>
      </article>
    <?php endwhile;endif; ?>

    <ul class="post-link">
      <li><?php previous_post_link('%link', '< 前の記事へ'); ?></li>
      <li><?php next_post_link('%link', '次の記事へ >'); ?></li>
    </ul>
  </main>

  <?php get_sidebar(); ?>
</div>

<?php get_footer(); ?>

style.css

別タブで開く
style.css

@charset "UTF-8";
/*
Theme Name: blog
*/
html {
  font-size: 100%;
}
body {
  color: #333;
  font-size: 1rem;
  font-family: 'Noto Sans', 'Noto Sans JP', sans-serif;
}
a {
  color: #333;
  text-decoration: none;
}
img {
  max-width: 100%;
}
li {
  list-style: none;
}
.wrapper {
  max-width: 1200px;
  padding: 0 16px;
  margin: 0 auto;
}
.readmore {
  font-size: 0.875rem;
  text-align: center;
}
.readmore a {
  padding-bottom: 1px;
  color: #333;
  position: relative;
}
.readmore a::after {
  content: '';
  position: absolute;
  height: 1px;
  width: 100%;
  left: 0;
  bottom: 0;
  background: #333;
  transition: all 200ms ease;
}
.readmore a:hover::after {
  opacity: 0;
  transform: translateY(3px);
}
.pagination ul {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
}
.pagination li {
  padding: 0 10px;
}
.pagination ul a:hover {
  opacity: 0.7;
}
.post-link {
  width: 300px;
  display: flex;
  justify-content: space-between;
  margin: 0 auto;
}

/*-------------------------------------------
header
-------------------------------------------*/
#header {
  width: 100%;
  background-color: #fff;
  position: fixed;
  z-index: 999;
}
#header .site-title {
  padding: 20px 16px;
  line-height: 1px;
}
#header .site-title a {
  display: inline-block;
}
#navi {
  background-color: #333;
}
#navi a {
  color: #fff;
}
#navi ul {
  display: flex;
  justify-content: flex-start;
  align-items: center;
}
#navi li {
  font-size: 0.875rem;
  padding: 10px 60px 10px 0;
}

/*-------------------------------------------
container
-------------------------------------------*/
#container {
  display: flex;
  justify-content: space-between;
  padding-top: 150px;
  margin-bottom: 60px;
}
main {
  width: 65%;
}
main article {
  margin-bottom: 80px;
}
main article img {
  height: auto;
}
main .page-title {
  border-bottom: solid 1px #777;
  font-size: 1.75rem;
  padding-bottom: 10px;
  margin-bottom: 60px;
}
main .article-title {
  font-size: 1.5rem;
  margin: 10px 0 15px 0;
}
main .meta {
  display: flex;
  justify-content: flex-start;
  margin-bottom: 10px;
}
main .meta li {
  font-size: 0.875rem;
  margin-right: 20px;
}
main .text {
  padding: 10px 40px 30px 40px;
}

/*-------------------------------------------
aside
-------------------------------------------*/
#sidebar {
  width: 33%;
  padding: 20px;
}
#sidebar .side-title {
  font-size: 1.125rem;
  font-weight: bold;
  margin-bottom: 30px;
}
#searchform {
  position: relative;
  margin-bottom: 60px;
}
#searchform button {
  position: absolute;
  top: 8px;
  right: 12px;
}
.author {
  text-align: center;
  margin-bottom: 60px;
}
.author img {
  width: 130px;
  height: 130px;
  border-radius: 50%;
  margin-bottom: 30px;
}
.author .profile {
  font-size: 0.875rem;
  text-align: left;
}
.archive {
  text-align: center;
  margin-bottom: 60px;
}
.archive ul {
  border-bottom: solid  1px #777;
}
.archive li {
  font-size: 0.875rem;
  border-top: solid  1px #777;
  padding: 20px;
  text-align: left;
}

/*-------------------------------------------
footer
-------------------------------------------*/
#footer {
  font-size: 0.875rem;
  background-color: #f7f7f7;
}
#footer .content {
  display: flex;
  justify-content: space-between;
  padding-top: 50px;
  padding-bottom: 50px;
}
#footer .item {
  width: 30%;
}
#footer .footer-title {
  font-size: 1.125rem;
  font-weight: bold;
  margin-bottom: 30px;
}
#footer ul.about-list {
  margin: 20px 0;
}
#footer ul.about-list li {
  margin-bottom: 5px;
}
#footer ul.about-list .arrow {
  position: relative;
  display: inline-block;
  padding-left: 12px;
  color: #333;
}
#footer ul.about-list .arrow::before {
  content: '';
  width: 0;
  height: 0;
  border-style: solid;
  border-width: 6px 0 6px 8px;
  border-color: transparent transparent transparent #333;
  position: absolute;
  top: 50%;
  left: 0;
  margin-top: -6px;
}
#footer .menu-list {
  border-bottom: solid  1px #777;
}
#footer .menu-list > li {
  border-top: solid  1px #777;
  padding: 15px;
  text-align: left;
}
#footer .copyright {
  font-size: 0.750rem;
  text-align: center;
  padding: 10px 0;
}

/*-------------------------------------------
contact form
-------------------------------------------*/
input,
textarea {
  width: 100%;
  border: solid 1px #c8c8c8;
  padding: 8px;
  margin-bottom: 10px;
}
input[type="submit"] {
  background-color: #333;
  color: #fff;
  padding: 15px 0;
}
input[type="submit"]:hover {
  opacity: 0.7;
}

/*-------------------------------------------
SP
-------------------------------------------*/
@media screen and (max-width: 767px) {
  .post-link {
    width: 100%;
  }

  /*-------------------------------------------
  header
  -------------------------------------------*/
  #header .site-title {
    padding: 20px 16px;
  }
  #navi {
    overflow-x: scroll;
  }

  /*-------------------------------------------
  container
  -------------------------------------------*/
  #container {
    flex-direction: column;
    padding-top: 140px;
  }
  main {
    width: 100%;
    margin-bottom: 80px;
  }
  main .text {
    padding: 10px 0;
  }

  /*-------------------------------------------
  aside
  -------------------------------------------*/
  #sidebar {
    width: 100%;
    padding: 0;
  }

  /*-------------------------------------------
  footer
  -------------------------------------------*/
  #footer .content {
    flex-direction: column;
  }
  #footer .item {
    width: 100%;
    margin-bottom: 30px;
  }
}