Я люблю Medium. Открытие отличное, и сообщество потрясающее, но мне также нужно место, где я могу разместить свое резюме, проекты и контактную информацию. Я также хотел отразить там свои публикации на Medium, поэтому я выбрал WordPress.

Из всех инструментов и фреймворков вам пришлось выбрать WordPress. Почему?

Помимо того факта, что с WordPress что-то не так, причины, по большей части, были косвенными. Изначально мой сайт был разработан на Jekyll, но, будучи опытным инженером, у меня была только учетная запись хостинга Namecheap и 20 долларов за домен.

Проблема в том, что общий план Namecheap не поддерживает приложения Ruby, поэтому я запускал Jekyll локально и загружал папку _site каждый раз, когда обновлял свой блог. Излишне говорить, что мне это довольно быстро надоело. Я создал множество веб-сайтов WordPress, когда учился в колледже, и, поскольку Namecheap в основном работает со стеком LAMP, я решил, что это прекрасная возможность освежить свои навыки PHP.

Как я это сделал

Я начал с чистой установки WordPress в моей локальной среде. Там я создал папку с именем wp-johnfajardo внутри папки ./wp-content/themes. Затем внутри своей папки темы я создал папку ./src, в которой я настроил быстрый конвейер Gulp для создания моих стилей CSS через SCSS:

wp-johnfajardo // This is the theme root folder.
├── content-single.php
├── fonts
│   ├── icomoon.eot
│   ├── icomoon.svg
│   ├── icomoon.ttf
│   └── icomoon.woff
├── footer.php
├── functions.php
├── header.php
├── images
│   ├── profile.png
│   └── wave.jpg
├── index.php
├── lib
│   └── prettify
│       ├── lang-css.js
│       ├── lang-go.js
│       ├── lang-lua.js
│    [...]
│       ├── lang-yaml.js
│       ├── lang-yml.js
│       ├── prettify.css
│       ├── prettify.js
│       ├── run_prettify.js
│       └── skins
│           ├── desert.css
│           ├── doxy.css
│           ├── sons-of-obsidian.css
│           └── sunburst.css
├── page.php
├── screenshot.png
├── sidebar.php
├── single.php
├── src
│   ├── gulpfile.babel.js
│   ├── images
│   ├── package.json
│   ├── package-lock.json
│   └── scss
│       ├── fonts
│       └── style.scss
└── style.css

Хотя это выглядит немного устрашающе, на самом деле не так уж и плохо. Давайте на мгновение проигнорируем .php файлы и рассмотрим структуру каталогов:

  • В папке ./fonts хранится набор иконок-шрифтов, которые я использовал для иконок телефона и социальных сетей.
  • В папке ./images есть… ну, изображения, которые использует моя тема.
  • ./libdirectory содержит любые внешние библиотеки. В моем случае я использую prettify для выделения кода. Его сняли с производства, но он все еще довольно популярен и широко используется.
  • И, наконец, каталог ./src содержит все мои зависимости разработчиков для моего стиля. Для этого не обязательно запускать проект Gulp, но я так привык писать SASS, что простой CSS кажется мне странным. Это упрощенная версия проекта из Gulp post, сделанная только для SASS, поэтому обратитесь к ней, чтобы узнать, как ее настроить.

Файлы php и иерархия тем

Тема WordPress вращается вокруг index.php файла. Это первый файл, который читается при загрузке страницы. Однако он не содержит полной страницы. Вместо этого каждый раздел страницы находится в собственном файле, и индекс вызывает их по мере необходимости для сборки страницы:

Итак, имея эти знания, давайте взглянем на файлы в нашем проекте:

  • Файл index.php, как объяснялось ранее, является основным файлом, и он загружает все остальные.
  • ./sidebar.php и ./footer.php говорят сами за себя, это другие области страницы.
  • В WordPress есть разные типы контента, у вас есть обычные сообщения в блогах и более статичные страницы. Вы можете определить их внешний вид индивидуально с помощью файлов./page.php и ./single.php.
  • ./content-single.php вызывается из ./single.php для дальнейшего построения нашей индивидуальной страницы сообщений. Если вы работаете в Rails, подумайте о #show своего рода представлении.
  • ./style.css говорит само за себя.
  • Наконец, у нас есть файл ./functions.php. Если вам нужно настроить способ работы WordPress по умолчанию, вы можете это сделать здесь.

index.php

<?php get_header(); ?>
<div class="container">
    <?php get_sidebar(); ?>
    <div class="content">
        <h2 class="latest-posts">Latest posts</h2>
        <hr class="main-separator" />
        <?php while ( have_posts() ) : the_post(); ?>
        <article>
            <h3 class="post-title"><a href="<?php echo get_permalink(); ?>"><?php the_title(); ?></a></h3>
            <p class="metadata"><span class="icon-calendar"></span> <?php the_date();?> -  <span class="icon-user"> </span>  <?php the_author();?></p>
            <?php the_content(); ?>
        </article>
        <hr class ="separator" />
        <?php endwhile; ?>
        <?php get_footer(); ?>

    </div><!--  End content -->
</div> <!-- End container -->
</body>
</html>

Это центральная часть темы. Он вызывает заголовок и боковую панель, а затем запускает «средний» раздел страницы, где он извлекает сообщения из базы данных, а затем перебирает результат для отображения списка сообщений. Затем он получает нижний колонтитул и все.

header.php

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
    <title><?php bloginfo( 'name' ); ?></title>
    <link href="https://fonts.googleapis.com/css?family=Lato|Roboto:400&display=swap" rel="stylesheet">
    <link rel="stylesheet" href="<?php bloginfo( 'stylesheet_url' ); ?>">    
    <link rel="stylesheet" href="<?php echo get_stylesheet_directory_uri(); ?>/lib/prettify/skins/sunburst.css">
    <script src="<?php echo get_stylesheet_directory_uri(); ?>/lib/prettify/run_prettify.js"></script>
    <script>
        document.addEventListener('DOMContentLoaded', function() {
            var pres = document.querySelectorAll('pre');
            pres.forEach(pre => {
                pre.classList.add('prettyprint', 'sunburst')
            });
        });
    </script>
    <?php wp_head(); ?>
</head>
<body onload="PR.prettyPrint()">

Этот файл инициализирует раздел заголовка каждой страницы, вызывает все соответствующие файлы javascript и таблиц стилей и, в нашем случае, инициализирует Prettify.

sidebar.php

<div class="navigation">
        <a href="<?php echo get_bloginfo('wpurl'); ?>" class="home-link"><img class="profile" src="<?php echo get_template_directory_uri(); ?>/images/profile.png" alt=""></a>
        <h1 class="title"><a href="<?php echo get_bloginfo('wpurl'); ?>">John Fajardo</a></h1>
        <p class="tagline">Software engineer</p>
        <nav>
            <!-- Walker -->
            <?php
                wp_nav_menu(array(
                    'container' => false,
                    'container_class' => false,
                    'container_id' => false,
                    'menu_class' => false,
                    'menu_id' => false,
                    'before' => '',
                    'after' => '',
                    'link_before' => '',
                    'link_after' => '',
                    'items_wrap' => '<ul class="nav-list">%3$s</ul>',
                    'walker'  => new Walker_Sidebar_Menu()
                ));
            ?>
            <!-- Walker -->
        </nav>
    </div><!--  End navigation -->

Довольно понятное дело. Всего пара ссылок и вызов внутренней wp_nav_menu функции WordPress для создания неупорядоченного списка ссылок на нашей странице.

footer.php

<?php post_pagination(); ?>

Я не использую нижний колонтитул ни для чего, кроме разбивки на страницы списка сообщений, так что это необходимо.

single.php

<?php get_header(); ?>
<div class="container">
    <?php get_sidebar(); ?>
    <div class="content main-content">
    <div class="post-content">
        <?php
            while ( have_posts() ) : the_post();
                get_template_part( 'content', 'single' );
            endwhile;
        ?>
    </div>

    </div><!--  End content -->
</div> <!-- End container -->
</body>
</html>

Этот файл загружается вместо ./index.php, когда мы открываем сообщение. Это в основном то же самое, за исключением того, что вместо вызова списков сообщений он вызывает ./content-single.php, который в конечном итоге является тем, который загружает сообщения, на которые был выполнен щелчок.

content-single.php

<article class="post">
    <h1><?php echo the_title(); ?></h1>
    <p><span class="icon-calendar"></span> 23 Sep 2019 -  <span class="icon-user"> </span>  John</p>
    <hr class="post">
    <?php echo the_content(); ?>
</article>

Это файл, который фактически выполняет рендеринг отдельных сообщений. Я мог бы сделать это в файле ./single.php, но решил оставить его отдельно на тот случай, если в будущем я решу увеличить его.

page.php

<?php get_header(); ?>
<div class="container">
    <?php get_sidebar(); ?>
    <div class="content">
        <?php while ( have_posts() ) : the_post(); ?>
        <article>
            <?php the_content(); ?>
        </article>
        <hr class ="separator" />
        <?php endwhile; ?>
        <?php get_footer(); ?>

    </div><!--  End content -->
</div> <!-- End container -->
</body>
</html>

Это не очень СУХОЙ WordPress, но вот мы здесь. Опять же, у нас есть файл, который не только похож на файл ./index.php, но также загружается на свое место, на этот раз при нажатии на страницу.

functions.php

Здесь я сделал различные настройки, давайте рассмотрим их:

function johnsReadMore() {
    return '<a class="read-more" href="' . get_permalink() . '">Read More...</a>';
}
add_filter( 'the_content_more_link', 'johnsReadMore' );

Мне не понравилась ссылка «читать дальше» по умолчанию, поэтому я создал простую функцию, которая возвращает ее с разметкой, которую я хотел, а затем заменила стандартную ссылку на хук the_content_more_link.

function custom_sidebar() {
    $args = array(
        'id'            => 'primary',
        'name'          => __( 'Primary' ),
        'description'   => __( 'Appears on posts and pages in the sidebar.', 'text_domain' ),
        'before_title'  => '',
        'after_title'   => '',
        'before_widget' => '<li>',
        'after_widget'  => '</li>',
    );
    register_sidebar( $args );
}
add_action( 'widgets_init', 'custom_sidebar' );
register_nav_menus(
    array('my_theme_sidebar_menu' => 'Sidebar Menu' )
);
// Sidebar links
class Walker_Sidebar_Menu extends Walker {
    var $db_fields = array(
        'parent' => 'menu_item_parent', 
        'id'     => 'db_id' 
    );
    function start_el( &$output, $item, $depth = 0, $args = array(), $id = 0, $current_object_id = 'active' ) {
        $output .= sprintf( "\n<li class=\"menu-link\"><a href='%s'%s>%s</a></li>\n",
            $item->url,
            ( $item->object_id === get_the_ID() ) ? ' class="active"' : '',
            $item->title
        );
    }
}

Затем я сделал то же самое с боковой панелью. Я создал новый со своими предпочтениями. Поскольку это настраиваемая функция, я зарегистрировал ее как действие, а не как фильтр. Затем я расширил класс Walker, чтобы добавить свою разметку.

if ( ! function_exists( 'post_pagination' ) ) :
    function post_pagination() {
        global $wp_query;
        $pager = 999999999; // need an unlikely integer
        $paginate_links = paginate_links( array(
            'base' => str_replace( $pager, '%#%', esc_url( get_pagenum_link( $pager ) ) ),
            'format' => '?paged=%#%',
            'current' => max( 1, get_query_var('paged') ),
            'prev_text' => __('<<'),
            'next_text' => __('>>'),
            'type' => 'list',
            'total' => $wp_query->max_num_pages
        ));
        $paginate_links = str_replace( "<ul class='page-numbers'>", "<ul class='pagination'>", $paginate_links );
        if ( $paginate_links ) {
            echo $paginate_links;
        }
    }
endif;

И, наконец, я создаю функцию разбивки на страницы, в которой я снова указал желаемую разметку, но на этот раз ее не нужно регистрировать. Вместо этого он вызывается непосредственно в ./footer.phpfile.

И это почти все, что нужно для создания собственных тем WordPress. Мы взглянули на него очень быстро, но рабочий процесс в основном тот же: найдите что-то, что вам не нравится, обратитесь к документации тем и измените это.
Надеюсь, этот пост был для вас полезен, и если если вам интересно, нажмите здесь, чтобы проверить живую версию, и здесь, чтобы перейти в репозиторий.