29 β Performans va tarqatish¶
β¬ οΈ Oldingi: 28 β i18n/l10n va accessibility Β· π README Β· Keyingi: 30 β Yakuniy loyiha: to'liq professional tema β‘οΈ
Bu bobda: tema deyarli tayyor β endi uni tez va tarqatishga yaroqli qilamiz. Avval performans: faqat kerakli sahifada asset ulash (shartli enqueue), rasmlarni to'g'ri o'lcham va lazy-load bilan berish,
WP_Queryso'rovlarini yengillashtirish (no_found_rows, kerakli maydon), qimmat so'rovlarni transient va object cache bilan keshlash, hamda block temaning tabiiy performans afzalligi va Core Web Vitals. Keyin child (bola) tema: nima, qachon vastyle.cssTemplate:header +functions.phporqali parent stilini to'g'ri ulash. Yakunda tarqatish: Theme Check plagini, WordPress.org tema katalogi talablari (GPL, prefiks, escaping, no-tracking), versiyalash va premium tema sotish. Bobdagi barcha PHPphp -lbilan, transient/funksiyalar va child-tema bog'lanishi esa jonli WordPress 7.0 da tasdiqlangan.
Nega performans tema ishi?¶
Ko'pchilik "saytni tezlashtirish" deganda kesh plagini yoki CDN ni tasavvur qiladi. Lekin tema ham tezlikka bevosita ta'sir qiladi: har sahifada nechta CSS/JS yuklanadi, rasmlar qancha "og'ir", baza necha marta so'roq qilinadi β bularning hammasi temaning kodida hal bo'ladi. Yomon yozilgan tema hech qanday kesh plagini to'liq tuzata olmaydi.
O'xshatish: tema β bu restorandagi oshpaz. Mijoz (brauzer) qanchalik tez ovqat olishi nafaqat yetkazib beruvchiga (server/CDN), balki oshpaz qancha keraksiz idish ishlatishiga va buyurtmani qanday tayyorlashiga bog'liq. Bu bobda biz oshpazni intizomli qilamiz: faqat kerakli idishni olamiz, ortiqcha yurishni kamaytiramiz.
Performansning uchta asosiy o'qi bor:
| O'q | Muammo | Tema yechimi |
|---|---|---|
| Asset | Ortiqcha CSS/JS har sahifada | Shartli enqueue, defer, minify |
| Rasm | Og'ir, noto'g'ri o'lchamli rasm | Mos o'lcham, lazy-load, WebP, srcset |
| Baza | Ko'p/og'ir WP_Query so'rovlar |
Optimizatsiya + transient/object kesh |
Asset optimizatsiya: faqat kerakligini yukla¶
10-bobda wp_enqueue_style/wp_enqueue_script bilan asset ulashni o'rgandik. Endi muhim qoida: har asset har sahifada kerak emas. Slayder JS faqat bosh sahifada, kontakt forma CSS faqat kontakt sahifasida kerak. Hammasini hamma joyda yuklash β mijozni keraksiz idish-tovoq bilan to'ldirish demak.
Shartli enqueue¶
Yechim β wp_enqueue_scripts hooki ichida shartli teglar (6-bob) bilan ajratish:
add_action( 'wp_enqueue_scripts', 'kitob_assets' );
function kitob_assets() {
$ver = wp_get_theme()->get( 'Version' ); // kesh-buzish uchun versiya
// Umumiy stil β har sahifada kerak.
wp_enqueue_style( 'kitob-style', get_stylesheet_uri(), array(), $ver );
// Slayder JS faqat bosh sahifada.
if ( is_front_page() ) {
wp_enqueue_script(
'kitob-slider',
get_theme_file_uri( 'assets/js/slider.js' ),
array(),
$ver,
array( 'strategy' => 'defer', 'in_footer' => true )
);
}
// Kontakt forma stili faqat 'page-kontakt.php' shablonida.
if ( is_page_template( 'page-kontakt.php' ) ) {
wp_enqueue_style( 'kitob-kontakt', get_theme_file_uri( 'assets/css/kontakt.css' ), array(), $ver );
}
// Izoh-javob skripti faqat izohlar ochiq postda.
if ( is_singular() && comments_open() && get_option( 'thread_comments' ) ) {
wp_enqueue_script( 'comment-reply' );
}
}
Bu yerda bir nechta texnik nozik nuqta bor:
get_theme_file_uri()βget_stylesheet_directory_uri() . '/...'ning qisqa va child-temaga mos varianti (avval child, keyin parent papkasidan qidiradi). Yangi temalarda shuni ishlating.array( 'strategy' => 'defer', 'in_footer' => true )βwp_enqueue_scriptning 5-argumenti (WP 6.3+).deferbrauzerga: "bu skriptni HTML tahlil tugagach yukla" deydi, bu render-blocking ni kamaytiradi. Eskitrue(faqat footer) o'rniga shu zamonaviy shaklni ishlating.comment-replyβ WordPress yadrosining ro'yxatdan o'tgan skripti; uni faqat kerak bo'lganda ulaymiz.
Anti-misol β har sahifada hamma narsa:
Bu foydalanuvchini 404 sahifasida ham slayder kodini yuklashga majbur qiladi.
Versiya bilan kesh-buzish (cache busting)¶
wp_enqueue_style/wp_enqueue_script ning 4-argumenti β versiya. WordPress uni URL ga ?ver=1.0.0 bo'lib qo'shadi. Versiyani o'zgartirsangiz, brauzer faylni yangi deb biladi va eski keshni tashlaydi. Shuning uchun versiyani wp_get_theme()->get('Version') (ya'ni style.css dagi Version:) ga bog'lash qulay β tema versiyasini ko'targaningizda asset keshi avtomatik yangilanadi.
nullversiya xavfi:$verninullqilsangiz, WordPress o'z yadro versiyasini qo'yadi β bu sizning faylingiz o'zgarsa ham keshni buzmaydi. Faylga doim aniq versiya bering.
Birlashtirish va minify¶
Ko'p kichik CSS/JS fayl β ko'p HTTP so'rov. Ikki yondashuv:
- Build vositasi bilan minify:
@wordpress/scripts(22-bob) yoki Sass/PostCSS bilan CSS/JS ni bitta minify qilingan faylga jamlang. Productiongastyle.min.cssni qo'ying, ishlab chiqishda esa to'liq versiyani. - Inline kichik kritik CSS: "above the fold" (ekranning birinchi qismi) uchun kerak bo'lgan ozgina CSS ni
wp_add_inline_style()bilan to'g'ridan-to'g'ri<head>ga qo'yib, qolganini kechiktirsangiz, birinchi bo'yoq (First Paint) tezlashadi.
Eslatma: HTTP/2 davrida "hamma narsani bitta faylga jamlash" eski qoidasi yumshadi (parallel yuklash arzon). Lekin minify (bo'sh joy/komment olib tashlash) va keraksiz kodni umuman yubormaslik hamon foydali.
Rasm optimizatsiya¶
Ko'p saytda eng "og'ir" narsa β rasmlar. Tema ularni to'g'ri berishi shart.
Mos o'lchamli rasm va add_image_size¶
Agar 300px keng joyda 4000px li rasmni ko'rsatsangiz, brauzer behuda megabaytlarni yuklaydi. Yechim β har joy uchun mos o'lcham generatsiya qilish. after_setup_theme da add_image_size() bilan o'lcham ro'yxatdan o'tkazamiz:
add_action( 'after_setup_theme', 'kitob_image_sizes' );
function kitob_image_sizes() {
add_theme_support( 'post-thumbnails' );
add_image_size( 'kitob-karta', 600, 400, true ); // 600x400 ga qirqadi (crop)
add_image_size( 'kitob-keng', 1200, 9999, false ); // eni 1200, balandlik proportsional
}
Endi shablonda the_post_thumbnail( 'kitob-karta' ) deb shu o'lchamni so'raymiz β WordPress yuklangan rasmdan tegishli kichik nusxani beradi:
if ( has_post_thumbnail() ) {
the_post_thumbnail( 'kitob-karta', array( 'class' => 'kitob-thumb' ) );
}
Diqqat:
add_image_sizefaqat yangi yuklangan rasmlardan nusxa yasaydi. Mavjud rasmlar uchun "Regenerate Thumbnails" plagini yokiwp media regenerate(wp-cli) ishlatiladi.
Lazy-load (WP avtomatik bajaradi)¶
Ekrandan tashqaridagi rasmni darrov yuklamaslik β lazy loading. Yaxshi xabar: WordPress buni 5.5 dan beri avtomatik qiladi β the_post_thumbnail(), wp_get_attachment_image() va the_content() ichidagi rasmlarga loading="lazy" atributini o'zi qo'shadi. Jonli WP 7.0 da bu tasdiqlandi: wp_lazy_loading_enabled( 'img', 'the_content' ) β true.
Demak siz qo'lda hech narsa qilmaysiz β faqat the_post_thumbnail() kabi standart funksiyalarni ishlating, lazy-load tekin keladi.
Nozik nuqta β LCP rasmni lazy qilmang: sahifaning eng katta ko'rinadigan rasmi (masalan hero/bosh rasm) lazy bo'lmasligi kerak, aks holda u kechikadi. WordPress 6.3+ buni
wp_get_loading_optimization_attributes()orqali o'zi hal qiladi β birinchi katta rasmgafetchpriority="high"qo'yadi va lazy qilmaydi. Bu funksiya jonli WP 7.0 da mavjudligi tasdiqlandi.
srcset β responsive rasm¶
WordPress the_post_thumbnail() va wp_get_attachment_image() chiqishiga avtomatik srcset va sizes qo'shadi β brauzer ekran o'lchamiga qarab eng mos rasmni tanlaydi. Bu ham tekin keladi, faqat standart funksiyalardan foydalaning.
WebP / AVF zamonaviy formatlar¶
WebP β JPEG/PNG dan ancha kichik, sifati deyarli bir xil format. WordPress WebP yuklash va ko'rsatishni qo'llab-quvvatlaydi. Tema darajasida siz odatda foydalanuvchining yuklagan formatiga aralashmaysiz, lekin:
- Tema o'z rasmlarini (placeholder, ikona, fon) WebP/SVG da bering.
- Avtomatik JPEGβWebP konvertatsiya uchun "Performance Lab"/"Modern Image Formats" plaginini tavsiya qilish mumkin (bu tema emas, server/plagin ishi β halol ajratamiz).
Query (so'rov) optimizatsiya¶
Har WP_Query β bazaga bir yoki bir nechta SQL so'rov. Keraksiz so'rovlarni kamaytirish β temaning eng samarali optimizatsiyalaridan biri.
pre_get_posts bilan asosiy so'rovni sozlash¶
Asosiy (main) so'rovni o'zgartirish uchun yangi WP_Query yaratmang β bu qo'shimcha so'rov bo'ladi. O'rniga pre_get_posts hooki bilan mavjud asosiy so'rovni sozlang (5-bobda ko'rdik):
add_action( 'pre_get_posts', 'kitob_main_query' );
function kitob_main_query( $query ) {
if ( is_admin() || ! $query->is_main_query() ) {
return; // admin va ikkilamchi so'rovlarga tegmaymiz
}
if ( $query->is_home() ) {
$query->set( 'posts_per_page', 6 );
}
}
WP_Query ni yengillashtirish¶
Ikkilamchi so'rov yozganda (masalan "ommabop postlar"), faqat kerakli ma'lumotni so'rang:
$q = new WP_Query( array(
'posts_per_page' => 5,
'no_found_rows' => true, // SQL_CALC_FOUND_ROWS ni o'chiradi (pagination kerak emasligida)
'fields' => 'ids', // faqat ID kerak bo'lsa β to'liq post obyektini emas
'update_post_meta_cache' => false, // meta o'qimaymiz -> keshni to'ldirma
'update_post_term_cache' => false, // termlarni o'qimaymiz -> keshni to'ldirma
) );
| Parametr | Nima qiladi | Qachon |
|---|---|---|
no_found_rows => true |
Jami sonni hisoblamaydi | Pagination kerak bo'lmaganda |
fields => 'ids' |
Faqat ID qaytaradi | To'liq post kerak bo'lmasa |
update_post_meta_cache => false |
Meta keshini to'ldirmaydi | Meta o'qilmasa |
update_post_term_cache => false |
Term keshini to'ldirmaydi | Kategoriya/teg o'qilmasa |
posts_per_page => N |
Faqat N ta post | Doim aniq cheklang (-1 xavfli) |
posts_per_page => -1dan ehtiyot bo'ling: u "hamma postni ol" demak β 10 000 postli saytda bu xotira va vaqtni "yeydi". Doim aniq son qo'ying.
Transient kesh: qimmat so'rovni saqlash¶
Ba'zi so'rovlar qimmat: har sahifada bajarish ortiqcha. Masalan "eng ko'p ko'rilgan 5 post" ro'yxati har 5 sekundda o'zgarmaydi β uni keshlash mumkin. WordPress'ning Transients API aynan shu uchun: natijani vaqtinchalik saqlaydi va muddat tugaguncha qaytaradi.
Uchta funksiya:
set_transient( $kalit, $qiymat, $muddat )β keshga yozish (muddat sekundlarda);get_transient( $kalit )β keshdan o'qish (yo'q/eskirgan bo'lsafalse);delete_transient( $kalit )β keshni qo'lda o'chirish.
function kitob_ommabop_postlar() {
$kesh = get_transient( 'kitob_ommabop_postlar' );
if ( false !== $kesh ) {
return $kesh; // keshdan qaytaramiz β bazaga tegmaymiz
}
$q = new WP_Query( array(
'posts_per_page' => 5,
'meta_key' => 'korishlar_soni',
'orderby' => 'meta_value_num',
'order' => 'DESC',
'no_found_rows' => true,
'fields' => 'ids',
'update_post_meta_cache' => false,
'update_post_term_cache' => false,
) );
$natija = $q->posts;
wp_reset_postdata();
// 12 soatga keshlaymiz.
set_transient( 'kitob_ommabop_postlar', $natija, 12 * HOUR_IN_SECONDS );
return $natija;
}
Vaqt konstantalari (HOUR_IN_SECONDS = 3600, jonli WP da tasdiqlandi) kodni o'qiluvchan qiladi: MINUTE_IN_SECONDS, HOUR_IN_SECONDS, DAY_IN_SECONDS, WEEK_IN_SECONDS.
Keshni vaqtida tozalash (invalidatsiya)¶
Eng katta xato β keshni eskirgan holda qoldirish. Yangi post chiqqanda yoki ommaboplik o'zgarganda keshni tozalang:
add_action( 'save_post', 'kitob_keshni_tozala' );
function kitob_keshni_tozala() {
delete_transient( 'kitob_ommabop_postlar' );
}
Jonli verifikatsiya (illustrativ emas): transient ishlashi WP 7.0 da tekshirildi:
Massiv ham, oddiy qiymat ham to'g'ri saqlanib qaytdi; o'chirgandan keyinset_transient('kitob_arr', array(1,2,3), HOUR_IN_SECONDS); // -> true get_transient('kitob_arr'); // -> array(1,2,3) delete_transient('kitob_arr'); get_transient('kitob_arr'); // -> falsefalsekeldi.
Transient muddati β "yumshoq" kafolat¶
Muhim nuance: transient muddati kafolat emas. Object cache yoqilgan saytlarda kesh muddat tugashidan oldin ham o'chishi mumkin (xotira to'lsa). Shuning uchun doim false !== $kesh ni tekshiring va keshsiz holatga (qayta hisoblashga) tayyor bo'ling. Transientni "agar bo'lsa yaxshi" optimizatsiya deb qarang, "doim bo'ladi" deb emas.
Object cache va block tema afzalligi¶
Object cache¶
set_transient natijani odatda wp_options jadvaliga yozadi (qo'shimcha kesh-server yo'q bo'lsa). Lekin agar saytda persistent object cache (Redis/Memcached) yoqilgan bo'lsa, transientlar avtomatik o'sha tezkor xotiraga boradi β kodingizni o'zgartirmaysiz.
Bitta so'rov davomida takror ishlatiladigan qiymat uchun wp_cache_* ishlating (so'rov tugashi bilan o'chadi, agar persistent cache bo'lmasa):
function kitob_sayt_statistikasi() {
$kesh = wp_cache_get( 'kitob_stats', 'kitob' );
if ( false !== $kesh ) {
return $kesh;
}
$stats = array( 'jami' => wp_count_posts()->publish );
wp_cache_set( 'kitob_stats', $stats, 'kitob', 300 );
return $stats;
}
Jonli verifikatsiya:
wp_cache_set('k1','obj-val','kitob')βwp_cache_get('k1','kitob')WP 7.0 da'obj-val'qaytardi.wp_count_posts()ham mavjud.
Qisqa farq:
| Kesh turi | Saqlanish joyi | Yashash muddati |
|---|---|---|
| Transient | wp_options (yoki persistent cache) |
Muddatgacha (so'rovlar orasida saqlanadi) |
Object cache (wp_cache_*) |
Xotira | Bitta so'rov (persistent cache bo'lmasa) |
Block temaning performans afzalligi¶
15-21 boblarda ko'rgan block (FSE) temalar performansda tabiiy afzal:
- JS kam: klassik tema ko'pincha jQuery, slayder, menyu kabi maxsus skriptlar yuklaydi. Block tema ko'p funksiyani (galereya, akkordeon, navigatsiya) yadro bloklari bilan beradi β qo'shimcha JS shart emas.
- Stil faqat ishlatilgan blokga: WordPress block stillarini "per-block" yuklaydi (
should_load_separate_core_block_assets) β sahifada yo'q blokning CSS i yuklanmaydi. - theme.json β optimallashtirilgan CSS: 16-17 boblardagi
theme.jsonWordPress'ga faqat kerakli CSS o'zgaruvchilari va stillarni generatsiya qilish imkonini beradi. - Render-blocking kamroq: klassik temadagi katta
style.csso'rniga maydalangan, kontekstga bog'liq stillar.
Demak block tema tanlashning o'zi ko'pincha performans yutug'i (lekin sehr emas β baribir rasm/asset intizomi kerak).
Core Web Vitals¶
Google saytni reytinglashda Core Web Vitals (asosiy veb ko'rsatkichlar) ni hisobga oladi. Tema ularning har biriga ta'sir qiladi:
| Ko'rsatkich | Nima o'lchaydi | Tema nima qila oladi |
|---|---|---|
| LCP (Largest Contentful Paint) | Eng katta element qachon ko'rinadi | Hero rasmni lazy qilmaslik (fetchpriority), kritik CSS, server javobi |
| CLS (Cumulative Layout Shift) | Sahifa "sakraydimi" | Rasm/iframe ga width/height berish, font-ni barqaror yuklash |
| INP (Interaction to Next Paint) | Bosishga javob tezligi | Ortiqcha/og'ir JS ni kamaytirish, defer |
Amaliy maslahatlar:
- Rasmlarga doim o'lcham bering (CLS uchun) β the_post_thumbnail() buni o'zi qiladi.
- Shriftlarni font-display: swap bilan ulang (matn ko'rinmay turmasin).
- LCP rasmni lazy qilmang (yuqorida ko'rdik β WP buni o'zi hal qiladi).
- INP uchun: keraksiz JS yuborma, og'ir hisoblashlarni defer/async qil.
O'lchash: PageSpeed Insights, Lighthouse (Chrome DevTools), yoki "Site Health" β bularni ishlating. "Tez bo'ldi" deb taxmin qilmang, o'lchang.
Child (bola) tema¶
Child tema nima va nega kerak¶
Tasavvur qiling: tayyor temani (yoki o'zingiznikini) o'rnatgansiz va style.css ga ozgina o'zgartirish kiritdingiz. Keyin tema yangilandi β sizning o'zgartirishlaringiz yangi versiya bilan o'chib ketadi. Bu jiddiy muammo.
Yechim β child (bola) tema: u mavjud temaga (parentga) "tayanadi" va faqat siz o'zgartirmoqchi bo'lgan qismni ustiga yozadi. Parent yangilanganda child o'zgarishlari saqlanib qoladi.
O'xshatish: parent tema β uy loyihasi, child tema β uydagi mebel va dekoratsiya. Loyiha (parent) yangilansa, mebelingiz (child o'zgarishlar) joyida qoladi.
Qachon child tema ishlatish¶
| Holat | Child tema? |
|---|---|
| Tayyor (uchinchi tomon) temani sozlash | Ha β yangilanish saqlanadi |
| Mavjud temaga ozgina CSS/funksiya qo'shish | Ha |
| Noldan o'z temangizni yozish | Yo'q β to'g'ridan-to'g'ri yozing |
| Parentga jiddiy, tubdan o'zgartirish | Ko'pincha yo'q β alohida tema afzalroq |
Child tema tuzilishi¶
Child tema β eng kam holatda atigi bitta fayl: style.css. Asosiy siri β Template: headeri parentning papka nomini ko'rsatishi:
wp-content/themes/kitob-child/style.css:
/*
Theme Name: Kitob Child
Theme URI: https://example.com/kitob-child
Author: Oqil Imomnazarov
Description: Kitob temaning bola temasi.
Template: kitob
Version: 1.0.0
License: GNU General Public License v2 or later
License URI: http://www.gnu.org/licenses/gpl-2.0.html
Text Domain: kitob-child
*/
Template: kitob β bu yerda kitob parent temaning papka nomi (slug), Theme Name emas. Adashmang.
Parent va child stilini to'g'ri ulash¶
Eski qo'llanmalarda @import ko'rinadi β bu eskirgan va sekin (@import parallel yuklamaydi). To'g'ri usul β functions.php da wp_enqueue_style bilan avval parent, keyin child stilini ulash:
wp-content/themes/kitob-child/functions.php:
<?php
add_action( 'wp_enqueue_scripts', 'kitob_child_enqueue_styles' );
function kitob_child_enqueue_styles() {
$parent_handle = 'kitob-parent-style';
// 1) Parent style.css
wp_enqueue_style(
$parent_handle,
get_template_directory_uri() . '/style.css',
array(),
wp_get_theme( get_template() )->get( 'Version' )
);
// 2) Child style.css β parentga BOG'LIQ (dependency), keyin yuklanadi
wp_enqueue_style(
'kitob-child-style',
get_stylesheet_uri(),
array( $parent_handle ),
wp_get_theme()->get( 'Version' )
);
}
Bu yerda ikkita yo'l funksiyasini eslang (4-bobdan):
get_template_directory_uri()/get_template()β parent tema (Template);get_stylesheet_uri()/get_stylesheet_directory()β child (aktiv) tema (Stylesheet).
Child stilini parentga array( $parent_handle ) dependency bilan bog'lash uni parentdan keyin yuklashni kafolatlaydi β shunda child qoidalari parentni ustiga yozadi.
Nozik nuqta: ko'p block/FSE temalar
style.cssni asosiy CSS sifatida ishlatmaydi (stiltheme.jsondan keladi). Bunday parentlar uchun parentstyle.cssni ulash shart emasligini tekshiring β har temaning hujjatiga qarang. Yuqoridagi naqsh klassik (CSS asosli) parentlar uchun standart.
functions.php da child override¶
Child tema funksiyalari parent funksiyalaridan oldin yuklanadi. Parentdagi funksiyani almashtirish uchun parent muallifi function_exists() bilan o'rasa, child o'z versiyasini e'lon qila oladi. Aks holda parent funksiyasini hookdan olib (remove_action) o'zingiznikini qo'shasiz.
Jonli verifikatsiya (illustrativ emas): WP 7.0 da
ch29-parentvach29-childtest temalari yaratilib (AKTIVLASHTIRILMADI), bog'lanish READ-ONLY tekshirildi: -php -lβ childfunctions.phpda No syntax errors detected; -wp theme listβ ikkala tema ham ro'yxatda (ch29-child,ch29-parent), aktiv tema o'zgarmadi; -wp_get_theme('ch29-child')->parent()->get('Name')βCh29 Parentβ ya'niTemplate: ch29-parentheaderi haqiqiy parent-child bog'lanishini hosil qildi.
Child tema fayllari parentni qanday "ustiga yozishini" eslab qoling:
| Fayl turi | Override mantig'i |
|---|---|
Shablon (single.php, page.php ...) |
Child fayli butunlay parentnikini almashtiradi |
functions.php |
Ikkalasi ham yuklanadi (child oldin) β almashtirmaydi, qo'shadi |
style.css |
Enqueue tartibiga bog'liq (yuqoridagi naqsh) |
Tema tayyorlash: Theme Check¶
Temani tarqatishdan oldin uni standartlarga moslash kerak. Eng muhim vosita β rasmiy Theme Check plagini: u temangizni WordPress.org talablari bo'yicha avtomatik tekshiradi (xato, ogohlantirish, tavsiya).
Theme Check nimani tekshiradi (asosiy nuqtalar):
style.cssda majburiy headerlar (Theme Name,Version,License,Text Domain...);wp_head()(header.php) vawp_footer()(footer.php) chaqiriladimi;- Eskirgan/taqiqlangan funksiyalar ishlatilmaydimi;
- Chiqishlar escape qilinganmi (27-bob:
esc_html,esc_url,wp_kses_post); - Matnlar i18n qilinganmi (28-bob:
__(), text domain); - Taqiqlangan narsa yo'qmi (
base64, tahrirlangan yadro fayli, tracking, reklama...).
Ishlatish: plaginlardan Theme Check ni o'rnating va yoqing, keyin Appearance β Theme Check da temani tanlab "Check it!" bosing. Maqsad β REQUIRED (majburiy) xatolar 0 bo'lishi. WARNING/INFO larni ham iloji boricha tuzating.
Eslatma (halol): Theme Check natijasi sizning temangizning to'liq kodiga bog'liq, shuning uchun uni bu yerda "0 xato" deb ko'rsata olmaymiz β bu siz o'z temangizda bajaradigan qadam. Lekin bu bobdagi barcha kod namunalari escaping/i18n/headerlar qoidalariga rioya qilib yozilgan.
WordPress.org tema katalogiga tarqatish¶
WordPress.org rasmiy tema katalogi β tekin va eng katta tarqatish kanali. U yerga qabul qilinish uchun qat'iy talablar bor:
Asosiy talablar¶
| Talab | Tafsilot |
|---|---|
| GPL litsenziya | Tema VA undagi barcha resurslar (rasm, shrift, kutubxona) GPL-mos bo'lishi shart |
| Prefiks | Barcha funksiya/klass/global/hook nomlari noyob prefiks bilan (kitob_) β to'qnashuvni oldini oladi |
| Escaping | Har chiqish escape qilingan (27-bob) |
| Sanitization | Har kirish tozalangan (27-bob) |
| i18n | Barcha matn tarjima qilinadigan, text domain = tema slug (28-bob) |
| No tracking / no ads | Foydalanuvchini kuzatish, reklama, "phone home" yo'q |
| No yadro o'zgartirish | WordPress yadrosini o'zgartirmaydi |
wp_head/wp_footer |
Majburiy chaqiriladi |
| Xavfsizlik | Nonce, capability tekshiruvlari (27-bob) |
GPL nega muhim?¶
WordPress o'zi GPL litsenziyasida β uning ustida ishlaydigan temalar ham (kod jihatdan) GPL bo'lishi talab qilinadi. GPL sizga: kodni ishlatish, o'zgartirish, tarqatish va sotish huquqini beradi. Ya'ni GPL tema ham pullik bo'lishi mumkin β GPL "tekin" demak emas, "erkin" demak. Faqat resurslaringiz (shrift/rasm/JS kutubxona) ham GPL-mos litsenziyada bo'lsin.
Tarqatish jarayoni¶
- Temani
.zipqiling (papka nomi = tema slug). - Theme Check ni o'tkazing β REQUIRED xato 0.
- WordPress.org da yangi tema yuklang (
wordpress.org/themes/β Submit). - Avtomatik tekshiruv + inson reviewer ko'rib chiqadi (talablarga moslik).
- Tasdiqlangach tema katalogga tushadi va
wp.orgorqali avtomatik yangilanish oladi.
Versiyalash, yangilash va premium¶
Versiyalash¶
style.css dagi Version: β yagona haqiqat manbasi. Semantik versiyalash (SemVer) tavsiya etiladi:
MAJOR.MINOR.PATCHβ masalan2.3.1;- PATCH (1.0.1): xato tuzatish, orqaga mos;
- MINOR (1.1.0): yangi funksiya, orqaga mos;
- MAJOR (2.0.0): orqaga mos kelmaydigan o'zgarish.
Versiyani ko'targaningizda asset kesh-buzish (wp_get_theme()->get('Version')) avtomatik ishlaydi va foydalanuvchilarga yangilanish ko'rinadi.
Tema yangilash¶
- WordPress.org katalogidagi temalar avtomatik yangilanadi β yangi versiyani yuklasangiz, foydalanuvchilar bildirishnoma oladi.
- Katalogdan tashqari (premium) temalar o'z yangilanish mexanizmini talab qiladi: o'z serveringizda
Update URI:headeri (WP 5.8+) yoki maxsus update-server kodi.
Eslatma:
Update URI:headeri temangizni wordpress.org bo'lmagan manbadan yangilash uchun mo'ljallangan β bu wp.org katalogidagi tema bilan adashtirmaslik uchun ham foydali.
Premium tema sotish (ThemeForest va boshqalar)¶
Tema bilan pul ishlash yo'llari:
- ThemeMart / ThemeForest (Envato) kabi marketplace β katta bozor, lekin qat'iy sifat talablari va komissiya. Litsenziya odatda "split GPL" (PHP GPL, ba'zi resurslar cheklangan) β Envato qoidalarini o'qing.
- O'z sayti orqali sotish β to'liq nazorat, lekin marketing/qo'llab-quvvatlash o'zingizda.
- Freemium β tekin versiya wp.org da, kengaytmalar/Pro versiya pulli.
Muhim (halol): premium tema sifatini, sotuv jarayonini va daromadni bu kitobda "sinab" ko'rsata olmaymiz β bu biznes va platforma masalasi. Bizning ishimiz β kod sifatini (xavfsizlik, performans, standartlar) marketplace talablari darajasiga yetkazish; bu bobdagi va butun kitobdagi amaliyotlar aynan shu poydevorni beradi.
Yakuniy tekshiruv ro'yxati (tarqatishdan oldin)¶
| Bo'lim | Tekshiruv |
|---|---|
| Asset | Shartli enqueue, versiya bilan kesh-buzish, defer/footer |
| Rasm | add_image_size, mos o'lcham, lazy (avtomatik), o'lcham atributlari |
| Query | pre_get_posts, no_found_rows, kerakli fields, transient |
| Kesh | Transient invalidatsiya (save_post da tozalash) |
| Xavfsizlik | Escaping, sanitization, nonce (27-bob) |
| i18n | __(), text domain = slug, .pot (28-bob) |
| Accessibility | skip-link, ARIA, kontrast (28-bob) |
| Standart | Theme Check REQUIRED = 0, prefiks, GPL, wp_head/wp_footer |
| Versiya | style.css Version: (SemVer) |
Bu ro'yxat 30-bobdagi yakuniy loyihada to'liq qo'llaniladi.
Mashqlar¶
Oson¶
- Shartli enqueue.
wp_enqueue_scriptshookidakitob_assets()funksiyasini yozing: umumiystyle.csshar sahifada, lekinkitob-galereya.jsfaqatis_front_page()da ulansin (deferstrategiya bilan). Versiyawp_get_theme()->get('Version')bo'lsin.php -lbilan tekshiring. - Rasm o'lchami.
after_setup_themedaadd_image_size()bilankitob-kichik(300x300, crop) vakitob-banner(1600x500, crop) o'lchamlarini ro'yxatdan o'tkazing.add_theme_support('post-thumbnails')ni unutmang. - Lazy rasm. Shablon fragmenti yozing: agar postda thumbnail bo'lsa (
has_post_thumbnail),kitob-kichiko'lchamida ko'rsating. Lazy-load uchun qo'shimcha kod kerakmi β javobingizni izohda yozing. - Versiya kesh-buzish. Quyidagi yomon enqueue ni tuzating:
wp_enqueue_style( 'kitob', get_stylesheet_uri() );β unga versiya va dependency massivini to'g'ri qo'shing. - Child header.
kitob(papka nomi) temaning bola temasi uchunstyle.cssheaderini yozing: Theme Name "Kitob Bola", to'g'riTemplate:qatori, GPL litsenziya va text domain bilan.
O'rta¶
- Transient kesh qo'shish. "Tasodifiy iqtibos" (quote) ni qaytaradigan
kitob_iqtibos()funksiyasini yozing: agar transient bo'lsa undan qaytarsin, aks holda yangi qiymat hisoblab 1 soatga (HOUR_IN_SECONDS) keshlasin.php -lbilan tekshiring. - Kesh invalidatsiya. 6-mashqdagi keshni post saqlanganda (
save_post) tozalaydigan kodni qo'shing. Negadelete_transientkerakligini bir jumlada izohlang. - Query optimizatsiya. "Oxirgi 4 post" uchun
WP_Queryyozing, lekin faqat ID kerak:no_found_rows,fields => 'ids', meta/term keshni o'chiring.wp_reset_postdata()ni qo'shing.php -lbilan tekshiring. pre_get_posts. Asosiy so'rovni shunday sozlang: arxiv (is_archive) sahifalarida bir sahifada 12 post ko'rsatilsin, lekin admin va ikkilamchi so'rovlarga tegmang.php -lbilan tekshiring.- Child enqueue.
kitobparentning child temasifunctions.phpini yozing: avval parentstyle.css, keyin childstyle.cssni dependency bilan ulang. To'g'riget_template_directory_uri()/get_stylesheet_uri()ishlating.php -lbilan tekshiring.
Qiyin¶
- To'liq performans bloki. Bitta
functions.phpparchasi yozing: (a) shartli enqueue (bosh sahifada slayder, kontakt shablonda forma CSS), (b)add_image_sizeikkita o'lcham, (c) transient bilan keshlangan "ommabop postlar" funksiyasi +save_postda tozalash, (d)pre_get_postsda bosh sahifa 6 post.php -lbilan tekshiring. - Child tema yarat (to'liq).
kitobparent uchun to'liq child tema yarating:style.css(to'g'riTemplate:+ GPL + headerlar),functions.php(parent+child enqueue), vasingle.php(parentnikini override qiluvchi minimal shablon). Child shabloni qanday qilib parentnikini almashtirishini izohlang. - Object cache. Bitta so'rov davomida takror chaqiriladigan "menyu elementlari soni" ni
wp_cache_get/wp_cache_setbilan keshlaydigan funksiya yozing (kitobguruhida). Transientdan farqini bir jumlada izohlang. - Theme Check talablari. WordPress.org katalogiga yuborish uchun temangizda tekshiriladigan kamida 6 ta REQUIRED talabni sanab, har biri uchun kodda qanday ta'minlanishini bir misol bilan ko'rsating (escaping, i18n, prefiks, GPL,
wp_head/wp_footer, no-tracking). - LCP/CLS optimizatsiya. Hero rasm ko'rsatadigan shablon fragmenti yozing: rasm LCP element, shuning uchun lazy bo'lmasligi va
fetchpriority="high"olishi kerak. WordPress buni avtomatik qiladimi yoki qo'lda kerakmi β izohlang va to'g'ri yondashuvni kod bilan ko'rsating.
Yechimlar¶
Yechim β 1
<?php
add_action( 'wp_enqueue_scripts', 'kitob_assets' );
function kitob_assets() {
$ver = wp_get_theme()->get( 'Version' );
wp_enqueue_style( 'kitob-style', get_stylesheet_uri(), array(), $ver );
if ( is_front_page() ) {
wp_enqueue_script(
'kitob-galereya',
get_theme_file_uri( 'assets/js/kitob-galereya.js' ),
array(),
$ver,
array( 'strategy' => 'defer', 'in_footer' => true )
);
}
}
php -l β No syntax errors detected. Galereya JS faqat bosh sahifada, defer bilan render-blocking qilmaydi.
Yechim β 2
<?php
add_action( 'after_setup_theme', 'kitob_image_sizes' );
function kitob_image_sizes() {
add_theme_support( 'post-thumbnails' );
add_image_size( 'kitob-kichik', 300, 300, true ); // crop = true (aniq 300x300)
add_image_size( 'kitob-banner', 1600, 500, true ); // crop = true
}
4-argument true β qirqish (crop), aniq o'lchamga keltiradi. false bo'lsa proportsional kichraytiradi. Eslatma: bu o'lchamlar faqat yangi yuklangan rasmlarga avtomatik yasaladi.
Yechim β 3
<?php if ( has_post_thumbnail() ) : ?>
<?php the_post_thumbnail( 'kitob-kichik', array( 'class' => 'kitob-thumb' ) ); ?>
<?php endif; ?>
Lazy-load uchun qo'shimcha kod kerak emas: WordPress 5.5+ the_post_thumbnail() chiqishiga loading="lazy" ni avtomatik qo'shadi (jonli WP 7.0 da wp_lazy_loading_enabled β true bilan tasdiqlandi). srcset/sizes ham avtomatik qo'shiladi.
Yechim β 4
<?php
wp_enqueue_style(
'kitob',
get_stylesheet_uri(),
array(), // dependency yo'q
wp_get_theme()->get( 'Version' ) // aniq versiya -> kesh-buzish ishlaydi
);
Asosiy tuzatish β versiya. null (yoki bo'sh) versiya keshni buza olmaydi; style.css versiyasini bersak, tema yangilanganda asset keshi avtomatik yangilanadi.
Yechim β 5
/*
Theme Name: Kitob Bola
Theme URI: https://example.com/kitob-bola
Author: Oqil Imomnazarov
Description: Kitob temaning bola (child) temasi.
Template: kitob
Version: 1.0.0
License: GNU General Public License v2 or later
License URI: http://www.gnu.org/licenses/gpl-2.0.html
Text Domain: kitob-bola
*/
Template: kitob β parentning papka nomi (slug), Theme Name emas. Bu qator child temani parentga bog'laydi (jonli WP da Template: headeri parent-child bog'lanishini hosil qilishi tasdiqlandi).
Yechim β 6
<?php
function kitob_iqtibos() {
$kesh = get_transient( 'kitob_iqtibos' );
if ( false !== $kesh ) {
return $kesh;
}
$iqtiboslar = array(
'Kod yozish β fikrlashning bir turi.',
'Sodda yechim β eng yaxshi yechim.',
'O\'lchamasdan optimallashtirma.',
);
$tanlangan = $iqtiboslar[ array_rand( $iqtiboslar ) ];
set_transient( 'kitob_iqtibos', $tanlangan, HOUR_IN_SECONDS );
return $tanlangan;
}
php -l β No syntax errors detected. false !== $kesh tekshiruvi muhim: transient yo'q/eskirgan bo'lsa false qaytadi.
Yechim β 7
<?php
add_action( 'save_post', 'kitob_iqtibos_keshni_tozala' );
function kitob_iqtibos_keshni_tozala() {
delete_transient( 'kitob_iqtibos' );
}
delete_transient kerak, chunki kesh muddat (1 soat) tugaguncha eski qiymatni qaytaraveradi; yangilanish darhol ko'rinishi uchun keshni qo'lda tozalaymiz (kesh invalidatsiyasi).
Yechim β 8
<?php
$q = new WP_Query( array(
'posts_per_page' => 4,
'no_found_rows' => true,
'fields' => 'ids',
'update_post_meta_cache' => false,
'update_post_term_cache' => false,
) );
$idlar = $q->posts; // faqat ID massivi
wp_reset_postdata();
php -l β No syntax errors detected. fields => 'ids' to'liq post obyektlarini emas, faqat ID larni qaytaradi β pagination va meta/term kerak bo'lmaganda eng yengil so'rov.
Yechim β 9
<?php
add_action( 'pre_get_posts', 'kitob_arxiv_query' );
function kitob_arxiv_query( $query ) {
if ( is_admin() || ! $query->is_main_query() ) {
return;
}
if ( $query->is_archive() ) {
$query->set( 'posts_per_page', 12 );
}
}
php -l β No syntax errors detected. is_admin() va ! $query->is_main_query() tekshiruvlari admin panelga va ikkilamchi so'rovlarga tegmaslikni kafolatlaydi β bu pre_get_posts da eng muhim ehtiyot chorasi.
Yechim β 10
kitob-child/functions.php:
<?php
add_action( 'wp_enqueue_scripts', 'kitob_child_enqueue_styles' );
function kitob_child_enqueue_styles() {
$parent_handle = 'kitob-parent-style';
wp_enqueue_style(
$parent_handle,
get_template_directory_uri() . '/style.css', // PARENT papkasi
array(),
wp_get_theme( get_template() )->get( 'Version' )
);
wp_enqueue_style(
'kitob-child-style',
get_stylesheet_uri(), // CHILD (aktiv) style.css
array( $parent_handle ), // parentdan keyin yuklanadi
wp_get_theme()->get( 'Version' )
);
}
php -l β No syntax errors detected (jonli WP 7.0 da bir xil naqsh ch29-child da tekshirildi). get_template_directory_uri() β parent, get_stylesheet_uri() β child. Dependency massivi child stilini parentdan keyin yuklab, override ni kafolatlaydi.
Yechim β 11
<?php
// (a) Shartli enqueue
add_action( 'wp_enqueue_scripts', 'kitob_assets' );
function kitob_assets() {
$ver = wp_get_theme()->get( 'Version' );
wp_enqueue_style( 'kitob-style', get_stylesheet_uri(), array(), $ver );
if ( is_front_page() ) {
wp_enqueue_script( 'kitob-slider', get_theme_file_uri( 'assets/js/slider.js' ), array(), $ver, array( 'strategy' => 'defer', 'in_footer' => true ) );
}
if ( is_page_template( 'page-kontakt.php' ) ) {
wp_enqueue_style( 'kitob-kontakt', get_theme_file_uri( 'assets/css/kontakt.css' ), array(), $ver );
}
}
// (b) Rasm o'lchamlari
add_action( 'after_setup_theme', 'kitob_image_sizes' );
function kitob_image_sizes() {
add_theme_support( 'post-thumbnails' );
add_image_size( 'kitob-karta', 600, 400, true );
add_image_size( 'kitob-keng', 1200, 9999, false );
}
// (c) Transient kesh + invalidatsiya
function kitob_ommabop() {
$kesh = get_transient( 'kitob_ommabop' );
if ( false !== $kesh ) {
return $kesh;
}
$q = new WP_Query( array(
'posts_per_page' => 5,
'meta_key' => 'korishlar_soni',
'orderby' => 'meta_value_num',
'order' => 'DESC',
'no_found_rows' => true,
'fields' => 'ids',
'update_post_meta_cache' => false,
'update_post_term_cache' => false,
) );
$natija = $q->posts;
wp_reset_postdata();
set_transient( 'kitob_ommabop', $natija, 12 * HOUR_IN_SECONDS );
return $natija;
}
add_action( 'save_post', 'kitob_ommabop_tozala' );
function kitob_ommabop_tozala() {
delete_transient( 'kitob_ommabop' );
}
// (d) Asosiy so'rovni sozlash
add_action( 'pre_get_posts', 'kitob_main_query' );
function kitob_main_query( $query ) {
if ( is_admin() || ! $query->is_main_query() ) {
return;
}
if ( $query->is_home() ) {
$query->set( 'posts_per_page', 6 );
}
}
php -l β No syntax errors detected (bu kod jonli WP 7.0 da bobdagi snippet fayli orqali tasdiqlandi). To'rt qism birgalikda: asset intizomi + rasm o'lchami + keshlangan og'ir so'rov + yengillashtirilgan asosiy so'rov.
Yechim β 12
kitob-child/style.css:
/*
Theme Name: Kitob Bola
Author: Oqil Imomnazarov
Description: Kitob temaning child temasi.
Template: kitob
Version: 1.0.0
License: GNU General Public License v2 or later
License URI: http://www.gnu.org/licenses/gpl-2.0.html
Text Domain: kitob-bola
*/
kitob-child/functions.php:
<?php
add_action( 'wp_enqueue_scripts', 'kitob_child_styles' );
function kitob_child_styles() {
$parent = 'kitob-parent-style';
wp_enqueue_style( $parent, get_template_directory_uri() . '/style.css', array(), wp_get_theme( get_template() )->get( 'Version' ) );
wp_enqueue_style( 'kitob-child-style', get_stylesheet_uri(), array( $parent ), wp_get_theme()->get( 'Version' ) );
}
kitob-child/single.php (parentnikini override qiladi):
<?php
get_header();
while ( have_posts() ) :
the_post();
?>
<article <?php post_class( 'kitob-child-single' ); ?>>
<h1><?php the_title(); ?></h1>
<div class="kitob-meta"><?php echo esc_html( get_the_date() ); ?></div>
<?php the_content(); ?>
</article>
<?php
endwhile;
get_footer();
Override mantig'i: child temada single.php mavjud bo'lsa, WordPress template hierarchy (3-bob) bo'yicha child ni parentdan oldin tanlaydi β ya'ni child single.php parentnikini butunlay almashtiradi (qisman emas). functions.php esa boshqacha: child va parent ikkalasi yuklanadi. php -l β barchasi No syntax errors detected.
Yechim β 13
<?php
function kitob_menyu_soni() {
$kesh = wp_cache_get( 'kitob_menyu_soni', 'kitob' );
if ( false !== $kesh ) {
return $kesh;
}
$lokatsiyalar = get_nav_menu_locations();
$soni = count( $lokatsiyalar );
wp_cache_set( 'kitob_menyu_soni', $soni, 'kitob', 300 );
return $soni;
}
php -l β No syntax errors detected. Farq: wp_cache_* (object cache) qiymatni faqat bitta so'rov davomida saqlaydi (persistent cache bo'lmasa) β bir sahifa render davomidagi takroriy chaqiruvlarni tejaydi; transient esa so'rovlar orasida ham (wp_options yoki persistent cache da) saqlanadi.
Yechim β 14
WordPress.org katalogi REQUIRED talablari va kodda ta'minlash:
- Escaping β har chiqish escape qilingan:
- i18n β matn tarjima qilinadigan, text domain = slug:
- Prefiks β barcha nom noyob prefiksli (to'qnashuvni oldini oladi):
- GPL litsenziya β
style.cssda: va barcha resurslar (rasm/shrift/JS) GPL-mos. wp_head()/wp_footer()β header.php va footer.php da majburiy:- No tracking / no ads β foydalanuvchini kuzatuvchi, "phone home" yoki reklama kodi YO'Q; yadro fayllari o'zgartirilmagan.
(Qo'shimcha: sanitization β kirishni tozalash, nonce β forma/AJAX himoyasi; 27-bob.)
Yechim β 15
<?php
// Hero rasm β LCP element. Lazy QILMASLIK va fetchpriority="high" kerak.
if ( has_post_thumbnail() ) {
the_post_thumbnail(
'kitob-banner',
array(
'class' => 'kitob-hero',
'fetchpriority' => 'high',
'loading' => 'eager', // lazy emas (LCP ni kechiktirmaslik uchun)
)
);
}
Izoh: WordPress 6.3+ birinchi katta rasmni wp_get_loading_optimization_attributes() orqali ko'pincha avtomatik to'g'ri belgilaydi β LCP nomzodiga fetchpriority="high" qo'yadi va lazy qilmaydi (bu funksiya jonli WP 7.0 da mavjudligi tasdiqlandi). Lekin murakkab shablonda (masalan rasm slayder ichida) WP nomzodni noto'g'ri aniqlashi mumkin β shuning uchun ishonchli bo'lish uchun hero rasmga fetchpriority => 'high' va loading => 'eager' ni qo'lda ham berish maqbul. php -l β No syntax errors detected.
β¬ οΈ Oldingi: 28 β i18n/l10n va accessibility Β· π README Β· Keyingi: 30 β Yakuniy loyiha: to'liq professional tema β‘οΈ