Створення мінімальної теми WordPress з нуля

31 Likes Коментувати
Створення мінімальної теми WordPress з нуля

Для цього достатньо всього 3 файли: index.php, functions.php та style.css. В каталозі wp-content/themes добавляємо нову папку mynewtheme з пустими файлами index.php, functions.php, style.css.

На прикладі це буде простенька тема в якій через ajax-виклики можна в базу даних добавляти, видаляти та відображати записи авторизованим або не авторизованим користувачем.

В файл style.css добавляємо назву теми

/* Theme Name: My New Theme */
Code language: JSON / JSON with Comments (json)

В index.php HTML розмітку та JS код

<!doctype html> <html lang="uk"> <head> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1"> <link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" rel="stylesheet"> <title><?= THEME_NAME ?></title> </head> <body> <nav class="navbar navbar-expand-lg navbar-light bg-warning"> <div class="container-fluid"> <a class="navbar-brand" href="<?= home_url('/') ?>"><?= THEME_NAME ?></a> <button class="btn btn-dark btn-add-record">Новий запис</button> </div> </nav> <div class="container my-5"> <div class="list-records row"></div> </div> <script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/js/bootstrap.bundle.min.js"></script> <script src="https://code.jquery.com/jquery-3.6.0.min.js"></script> <!-- Шаблон запису --> <script type="text/html" id="template-record"> <div class="record p-2 col-md-4"> <div class="card"> <div class="card-body"> <h5 class="card-title"></h5> <p class="card-text"></p> <button href="#" class="btn btn-sm btn-danger btn-del-record">Видалити</button> </div> </div> </div> </script> <!-- Шаблон "Немає записів" --> <script type="text/html" id="template-no-records"> <div class="p-2 col-md-12"> <div class="card"> <div class="card-body"> <p class="card-text text-center">Немає записів</p> </div> </div> </div> </script> <!-- Шаблон модального вікна --> <script type="text/html" id="template-modal"> <div class="modal" tabindex="-1"> <div class="modal-dialog"> <div class="modal-content"> <div class="modal-header"> <h5 class="modal-title"></h5> <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button> </div> <div class="modal-body"></div> <div class="modal-footer"> <button type="button" class="btn btn-secondary btn-ok"></button> <button type="button" class="btn btn-primary btn-cancel"></button> </div> </div> </div> </div> </script> <script type="text/javascript"> /** * Отримання записів під час завантаження сторінки */ get_records(); /** * Кнопка "Новий запис" */ $(document).on('click', '.btn-add-record', function() { var modal = $($('#template-modal').html()); modal.find('.modal-title').html(`Новий запис`); modal.find('.btn-ok').html(`Добавити`); modal.find('.btn-cancel').html(`Відміна`).attr('data-bs-dismiss', 'modal'); modal.find('.modal-body').html(` <form> <input type="hidden" name="action" value="put_record"> <div class="mb-3"> <label class="form-label">Заголовок</label> <input type="text" class="form-control" name="title" required> </div> <div class="mb-3"> <label class="form-label">Текст</label> <textarea class="form-control" rows="6" name="body" required></textarea> </div> <input type="submit" hidden> </form> `); modal.on('hidden.bs.modal', function() { modal.remove(); }); modal.on('input', 'input,textarea', function() { modal.find('.alert').remove(); }); modal.on('submit', 'form', function(e) { e.preventDefault(); modal.find('.alert').remove(); $.post('<?= AJAX_URL ?>', $(this).serialize(), function(response) { if (response.success) { get_records(); $(`<div class="alert alert-success mb-0">${response.data}</div>`).insertAfter(modal.find('[type="submit"]')); setTimeout(function() { modal.modal('hide'); }, 1000); } else { $(`<div class="alert alert-danger mb-0">${response.data}</div>`).insertAfter(modal.find('[type="submit"]')); } }); }); modal.on('click', '.btn-ok', function() { modal.find('[type="submit"]').trigger('click'); }); modal.modal('show'); }); /** * Кнопка "Видалити" запис */ $(document).on('click', '.btn-del-record', function() { var record = $(this).closest('.record'), id = record.data('id'), title = record.find('.card-title').text(); var modal = $($('#template-modal').html()); modal.find('.modal-title').html(`Видалення запису`); modal.find('.btn-ok').html(`Видалити`); modal.find('.btn-cancel').html(`Відміна`).attr('data-bs-dismiss', 'modal'); modal.find('.modal-body').html(`<p>Ви дійсно бажаєте видалити запис "${title}"?</p>`); modal.on('hidden.bs.modal', function() { modal.remove(); }); modal.on('click', '.btn-ok', function() { modal.find('.alert').remove(); $.post('<?= AJAX_URL ?>', { action: 'del_record', id: id }, function(response) { if (response.success) { get_records(); modal.modal('hide'); } else { modal.find('.modal-body').append($(`<div class="alert alert-danger mb-0">${response.data}</div>`)); } }); }); modal.modal('show'); }); /** * Функція для отримання записів через AJAX */ function get_records() { $.get('<?= AJAX_URL ?>', { action: 'get_records' }, function(records) { if (records.length > 0) { var els = []; for (var record of records) { var el = $($('#template-record').html()); el.data('id', record.record_ID); el.find('.card-title').text(`#${record.record_ID} ${record.record_title}`); el.find('.card-text').text(record.record_body); els.push(el); } $('.list-records').html(els); } else { var el = $($('#template-no-records').html()); $('.list-records').html(el); } }); } </script> </body> </html>
Code language: HTML, XML (xml)

В functions.php наступне

<?php /** * Константи */ define('THEME_NAME', 'My New Theme'); define('AJAX_URL', admin_url('admin-ajax.php?theme=mynewtheme')); /** * Створюємо нову таблицю якщо не існує в базі даних */ $wpdb->query(" CREATE TABLE IF NOT EXISTS ".$wpdb->prefix."mynewtheme_records ( record_ID BIGINT UNSIGNED NOT NULL AUTO_INCREMENT, record_created TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, record_title VARCHAR(255) NOT NULL DEFAULT '', record_body TEXT, PRIMARY KEY(`record_ID`) ) ENGINE=InnoDB DEFAULT CHARSET=".DB_CHARSET."; "); /** * Прикріплення функцій до AJAX-викликів */ // Для авторизованих користувачів в WordPress add_action('wp_ajax_put_record' , 'put_record'); add_action('wp_ajax_del_record' , 'del_record'); add_action('wp_ajax_get_records', 'get_records'); // Для не авторизованих користувачів в WordPress add_action('wp_ajax_nopriv_put_record' , 'put_record'); add_action('wp_ajax_nopriv_del_record' , 'del_record'); add_action('wp_ajax_nopriv_get_records', 'get_records'); /** * Функція для додавання записів в базу даних */ function put_record() { global $wpdb; $title = !empty($_REQUEST['title']) ? sanitize_text_field($_REQUEST['title']) : ''; $body = !empty($_REQUEST['body']) ? sanitize_textarea_field($_REQUEST['body']) : ''; $result = $wpdb->insert( $wpdb->prefix.'mynewtheme_records', array( 'record_title' => $title, 'record_body' => $body ) ); if ($result !== false) wp_send_json_success('Добавлено успішно'); else wp_send_json_error('Щось пішло не так, спробуйте ще раз'); } /** * Функція для видалення запису із бази даних */ function del_record() { global $wpdb; $id = !empty($_REQUEST['id']) ? intval($_REQUEST['id']) : 0; $result = $wpdb->delete( $wpdb->prefix.'mynewtheme_records', array('record_ID' => $id) ); if ($result !== false) wp_send_json_success('Видалено успішно'); else wp_send_json_error('Щось пішло не так, спробуйте ще раз'); } /** * Функція для зчитування записів з бази даних */ function get_records() { global $wpdb; $records = $wpdb->get_results(' SELECT * FROM '.$wpdb->prefix.'mynewtheme_records ORDER BY record_created DESC '); wp_send_json($records); }
Code language: HTML, XML (xml)

Через майстерню WordPress активуємо новостворену тему (Вигляд -> Теми -> Активувати “My New Theme”).

P.S: Файли head.php, footer.php, та функції get_header(), get_footer(), wp_head(), wp_footer(), wp_enqueue_style(), wp_enqueue_script(), я не використовував, так як хотів показати мінімальний приклад теми WordPress 😝 .

Ось тут можна подивитись як все працює My New Theme

About the Author: Олександр

Залишити відповідь

Ваша e-mail адреса не оприлюднюватиметься. Обов’язкові поля позначені *