Dmitriy | init: Инициализация проекта.

This commit is contained in:
web_103.2 committed 2026-10-14 11:09:36 +03:00
commit 714d00cc6e
154 files changed
+19166

No files matched your search

+375
View File
@@ -0,0 +1,375 @@
<?php
// Настройки темы
function theme_setup() {
add_theme_support('title-tag');
add_theme_support('post-thumbnails', array('article', 'news', 'review'));
}
add_action('after_setup_theme', 'theme_setup');
// Скрыть админ бар
add_filter('show_admin_bar', '__return_false');
// Контроль версий css/js по дате изменения
function theme_asset_version($file) {
$file_path = get_theme_file_path($file);
if (file_exists($file_path)) {
return filemtime($file_path);
}
return wp_get_theme()->get('Version');
}
// Стили и скрипты темы
function theme_assets() {
// Стили
wp_enqueue_style('swiper', get_theme_file_uri('assets/libs/swiper/swiper-bundle.min.css'), array(), '12.1.4');
wp_enqueue_style('fancybox', get_theme_file_uri('assets/libs/fancybox/fancybox.css'), array(), '6.1.14');
wp_enqueue_style('theme-style', get_theme_file_uri('assets/css/style.css'), array(), theme_asset_version('assets/css/style.css'));
// Скрипты
wp_enqueue_script('swiper', get_theme_file_uri('assets/libs/swiper/swiper-bundle.min.js'), array(), '12.1.4', array('strategy' => 'defer'));
wp_enqueue_script('scroll-lock', get_theme_file_uri('assets/libs/scroll-lock/scroll-lock.js'), array(), '2.0.0', array('strategy' => 'defer'));
wp_enqueue_script('fancybox', get_theme_file_uri('assets/libs/fancybox/fancybox.umd.js'), array(), '6.1.14', array('strategy' => 'defer'));
wp_enqueue_script('theme-scripts', get_theme_file_uri('assets/js/scripts.js'), array(), theme_asset_version('assets/js/scripts.js'), array('strategy' => 'defer'));
// Данные калькулятора
wp_add_inline_script(
'theme-scripts',
'window.themeIncomeCalc = ' . wp_json_encode(
[
'rates' => [
'taxi' => get_field('income_taxi', 'option'),
'courier' => get_field('income_courier', 'option'),
'cargo' => get_field('income_cargo', 'option')
]
]
) . ';',
'before'
);
// AJAX
wp_add_inline_script(
'theme-scripts',
'window.themeAjax = ' . wp_json_encode(
[
'ajaxUrl' => admin_url('admin-ajax.php'),
'nonces' => [
'news' => wp_create_nonce('theme_news_nonce'),
'review' => wp_create_nonce('theme_review_nonce'),
'articles' => wp_create_nonce('theme_articles_nonce'),
'vacancies' => wp_create_nonce('theme_vacancies_nonce')
]
]
) . ';',
'before'
);
}
add_action('wp_enqueue_scripts', 'theme_assets');
// Стили для админки
function theme_admin_assets() {
wp_enqueue_style('theme-admin-style', get_theme_file_uri('assets/css/admin.css'), array(), theme_asset_version('assets/css/admin.css'));
}
add_action('admin_enqueue_scripts', 'theme_admin_assets', 100);
// Предзагрузка ресурсов
function theme_preload($preloads) {
$preloads[] = ['href' => get_theme_file_uri('assets/fonts/Onest-Regular.woff2'), 'as' => 'font', 'type' => 'font/woff2', 'crossorigin' => 'anonymous'];
$preloads[] = ['href' => get_theme_file_uri('assets/fonts/Onest-Medium.woff2'), 'as' => 'font', 'type' => 'font/woff2', 'crossorigin' => 'anonymous'];
$preloads[] = ['href' => get_theme_file_uri('assets/fonts/Onest-SemiBold.woff2'), 'as' => 'font', 'type' => 'font/woff2', 'crossorigin' => 'anonymous'];
$preloads[] = ['href' => get_theme_file_uri('assets/fonts/Onest-Bold.woff2'), 'as' => 'font', 'type' => 'font/woff2', 'crossorigin' => 'anonymous'];
$preloads[] = ['href' => get_theme_file_uri('assets/img/icons/logo.svg'), 'as' => 'image', 'fetchpriority' => 'high'];
return $preloads;
}
add_filter('wp_preload_resources', 'theme_preload');
// Подключение Яндекс-карт
function theme_ymaps() {
if (!is_page_template('templates/template-contacts.php')) {
return;
}
wp_enqueue_script('ymaps-api', 'https://api-maps.yandex.ru/v3/?apikey=bdb94b0e-bc76-4928-859f-4061373c1894&lang=ru_RU', array(), null, array('strategy' => 'async'));
wp_enqueue_script('ymaps-map', get_theme_file_uri('assets/js/map.js'), array('ymaps-api'), theme_asset_version('assets/js/map.js'), array('strategy' => 'defer'));
$contacts = get_field('contacts', 89);
$coords_array = array_map('floatval', explode(',', $contacts['coords']));
$map_data = wp_json_encode([
'coordinates' => $coords_array,
'address' => $contacts['address'],
'markerIconUrl' => get_theme_file_uri('assets/img/icons/placemark.svg')
]);
wp_add_inline_script('ymaps-map', 'window.contactsMapData = ' . $map_data . ';', 'before');
}
add_action('wp_enqueue_scripts', 'theme_ymaps');
// Регистрация меню
function theme_register_menus() {
register_nav_menus([
'header-menu' => 'Меню в шапке',
'footer-menu' => 'Меню в футере'
]);
}
add_action('after_setup_theme', 'theme_register_menus');
// Вывод меню
function theme_menu($name, $args = []) {
$block = !empty($args['menu_block'])
? $args['menu_block']
: $name . '-menu';
$defaults = [
'theme_location' => $name . '-menu',
'container' => 'nav',
'container_class' => $block,
'menu_block' => $block,
'menu_class' => $block . '__list',
'items_wrap' => '<ul class="%2$s">%3$s</ul>',
'submenu_toggle' => false,
'fallback_cb' => false,
'depth' => 2,
'walker' => new Theme_Menu_Walker()
];
wp_nav_menu(array_merge($defaults, $args));
}
// Кастомные размеры картинок
function theme_image_sizes() {
remove_image_size('1536x1536');
remove_image_size('2048x2048');
add_image_size('extra_large', 1280, 1280, false);
}
add_action('after_setup_theme', 'theme_image_sizes');
// Добавить большой размер картинок в селектор
function theme_image_size_names_choose($sizes) {
$new_sizes = [];
foreach ($sizes as $size => $label) {
if ($size === 'full') {
$new_sizes['extra_large'] = 'Огромный';
}
$new_sizes[$size] = $label;
}
return $new_sizes;
}
add_filter('image_size_names_choose', 'theme_image_size_names_choose');
// Максимальный размер картинок
function theme_big_image_size_threshold() {
return 1920;
}
add_filter('big_image_size_threshold', 'theme_big_image_size_threshold');
// Скрыть пункты меню в админке
function remove_admin_menu_items() {
remove_menu_page('edit.php');
remove_menu_page('edit-comments.php');
}
add_action('admin_menu', 'remove_admin_menu_items');
// Перевести число в текст
function numToWords($number) {
$units = ['', 'first', 'second', 'third', 'fourth'];
$words = $units[$number];
return $words;
}
// Редирект QR-кода на правильный стор
add_action('template_redirect', function () {
if (!is_page('download')) {
return;
}
if (($_GET['redirect'] ?? '') !== 'app') {
return;
}
$download = get_field('download', 'option');
if (empty($download) || !is_array($download)) {
return;
}
$gplay = $download['gplay'] ?? '';
$appstore = $download['appstore'] ?? '';
$rustore = $download['rustore'] ?? '';
$appgallery = $download['appgallery'] ?? '';
$ua = strtolower($_SERVER['HTTP_USER_AGENT'] ?? '');
$has = fn($v) => str_contains($ua, $v);
$isAndroid = $has('android');
$isIOS = (
$has('iphone') ||
$has('ipod') ||
$has('ipad') ||
(
$has('macintosh') &&
$has('applewebkit') &&
!$has('android') &&
!$has('windows') &&
!$has('linux')
)
);
$isHuawei = $has('huawei') || $has('honor');
if ($isIOS && $appstore) {
wp_redirect($appstore, 302);
exit;
}
if ($isAndroid) {
if ($isHuawei && $appgallery) {
wp_redirect($appgallery, 302);
exit;
}
if ($gplay) {
wp_redirect($gplay, 302);
exit;
}
if ($rustore) {
wp_redirect($rustore, 302);
exit;
}
}
});
// Фикс сдвига контента
function reload_paint_guard() { ?>
<style id="reload-paint-guard-css">
html.is-reload-guard {
opacity: 0 !important;
}
</style>
<script id="reload-paint-guard-js">
(function() {
var isReload = false;
try {
var nav = performance.getEntriesByType('navigation')[0];
isReload = nav ? nav.type === 'reload' :
performance.navigation.type === 1;
} catch (e) {}
if (!isReload) return;
document.documentElement.classList.add('is-reload-guard');
var frames = 0;
function waitFrames() {
if (++frames < 10) {
requestAnimationFrame(waitFrames);
return;
}
document.documentElement.classList.remove('is-reload-guard');
}
requestAnimationFrame(waitFrames);
})();
</script>
<?php }
add_action('wp_enqueue_scripts', 'reload_paint_guard', 0);
// Описание в карточках
function get_card_descr($descr_field, $words = 25, $content_field = 'article_content', $post_id = null) {
$post_id = $post_id ?: get_the_ID();
if (! $post_id || ! function_exists('get_field')) {
return '';
}
$descr = get_field($descr_field, $post_id, false);
$descr = trim(wp_strip_all_tags(strip_shortcodes($descr)));
if ($descr !== '') {
return $descr;
}
$content = get_field($content_field, $post_id, false);
$content = trim(wp_strip_all_tags(strip_shortcodes($content)));
if ($content === '') {
return '';
}
return wp_trim_words($content, $words, '...');
}
// Генерация содержания статей из заголовков
function generate_toc($content, $id_prefix = 'section') {
$toc_items = [];
$toc_index = 0;
$processed = preg_replace_callback(
'~<h2([^>]*)>(.*?)</h2>~isu',
function ($m) use (&$toc_items, &$toc_index, $id_prefix) {
$title = trim(wp_strip_all_tags($m[2]));
if ($title === '') {
return $m[0];
}
$toc_index++;
$attrs = $m[1];
if (preg_match('~\sid=(["\'])(.*?)\1~i', $attrs, $id_match)) {
$id = $id_match[2];
} else {
$id = $id_prefix . '-' . $toc_index;
$attrs = rtrim($attrs) . ' id="' . esc_attr($id) . '"';
}
$toc_items[] = ['id' => $id, 'title' => $title];
return '<h2' . $attrs . '>' . $m[2] . '</h2>';
},
$content
);
return [
'content' => $processed ?? $content,
'toc_items' => $toc_items,
];
}
// Исключить таксономии из карты сайта
add_filter('wpseo_sitemap_exclude_taxonomy', function ($excluded, $taxonomy) {
$excluded_taxonomies = [
'article_category',
'landing_category',
'vacancy_category',
];
if (in_array($taxonomy, $excluded_taxonomies, true)) {
return true;
}
return $excluded;
}, 10, 2);
// Яндекс-метрика
function theme_yandex_metrika() {
if (is_admin()) return;
?>
<!-- Yandex.Metrika counter -->
<script type="text/javascript">
(function(m, e, t, r, i, k, a) {
m[i] = m[i] || function() {
(m[i].a = m[i].a || []).push(arguments)
};
m[i].l = 1 * new Date();
for (var j = 0; j < document.scripts.length; j++) {
if (document.scripts[j].src === r) {
return;
}
}
k = e.createElement(t), a = e.getElementsByTagName(t)[0], k.async = 1, k.src = r, a.parentNode.insertBefore(k, a)
})(window, document, 'script', 'https://mc.yandex.ru/metrika/tag.js', 'ym');
ym(100213356, 'init', {
webvisor: true,
clickmap: true,
referrer: document.referrer,
url: location.href,
accurateTrackBounce: true,
trackLinks: true
});
</script>
<noscript>
<div><img src="https://mc.yandex.ru/watch/100213356" style="position:absolute; left:-9999px;" alt="" /></div>
</noscript>
<!-- /Yandex.Metrika counter -->
<?php }
add_action('wp_head', 'theme_yandex_metrika', 1);
// Подключение функций
require_once get_template_directory() . '/inc/acf.php';
require_once get_template_directory() . '/inc/ajax.php';
require_once get_template_directory() . '/inc/menu.php';
require_once get_template_directory() . '/inc/breadcrumbs.php';