Capitol gratuit

Arhitectura WordPress

Înțelegerea arhitecturii interne a WordPress este fundamentală pentru dezvoltarea avansată. WordPress este construit pe PHP și MySQL/MariaDB, folosind un m...

Structura fișierelor WordPress

Înțelegerea arhitecturii interne a WordPress este fundamentală pentru dezvoltarea avansată. WordPress este construit pe PHP și MySQL/MariaDB, folosind un model bazat pe hooks (actions și filters).


wordpress/
├── wp-admin/              ← Interfața de administrare (NU modificați!)
├── wp-includes/           ← Core WordPress (NU modificați!)
├── wp-content/            ← SINGURA zonă pe care o modificați
│   ├── themes/            ← Temele instalate
│   │   ├── tema-activa/
│   │   └── tema-copil/
│   ├── plugins/           ← Pluginurile instalate
│   │   ├── plugin-1/
│   │   └── plugin-2/
│   ├── uploads/           ← Media (imagini, documente, video)
│   │   └── 2026/03/
│   ├── mu-plugins/        ← Must-Use Plugins (se încarcă automat)
│   ├── languages/         ← Fișiere de traducere
│   └── upgrade/           ← Fișiere temporare actualizare
├── wp-config.php          ← Configurare principală
├── wp-login.php           ← Pagina de login
├── wp-cron.php            ← Sistem de sarcini programate
├── wp-settings.php        ← Inițializare WordPress
├── index.php              ← Punct de intrare principal
├── .htaccess              ← Configurare Apache/LiteSpeed
└── xmlrpc.php             ← API vechi (dezactivați-l!)
⚠️ Regulă de aur

NU modificați NICIODATĂ fișierele din wp-admin/ sau wp-includes/. Orice modificare va fi suprascrisă la următoarea actualizare WordPress. Folosiți DOAR wp-content/ (teme, pluginuri, mu-plugins) pentru personalizări.

Ciclul de viață al unui request WordPress

Când un vizitator accesează o pagină WordPress, se parcurg următorii pași:

  1. index.php - punctul de intrare, încarcă wp-blog-header.php
  2. wp-config.php - se citesc constantele și setările
  3. wp-settings.php - inițializare core, încărcare funcții
  4. mu-plugins - se încarcă Must-Use Plugins
  5. plugins - se încarcă pluginurile active
  6. tema activă - functions.php al temei se încarcă
  7. init hook - se declanșează hook-ul init
  8. WP_Query - WordPress determină ce conținut să afișeze (parse request)
  9. template_redirect - se selectează template-ul potrivit
  10. Template Hierarchy - se încarcă fișierul template corespunzător
  11. wp_head / wp_footer - se generează head-ul și footer-ul
  12. shutdown - se finalizează execuția

Structura bazei de date WordPress

WordPress folosește implicit 12 tabele (prefix wp_ sau cel setat la instalare):

TabelăConținutRânduri tipice
wp_postsArticole, pagini, CPT-uri, revizii, meniuriMii - zeci de mii
wp_postmetaMetadate pentru posts (câmpuri custom)Zeci/sute de mii
wp_usersUtilizatorii înregistrațiVariabil
wp_usermetaMetadate utilizatorix10 per user
wp_optionsSetări WordPress, plugin-uri, temeSute - mii
wp_commentsComentariiVariabil
wp_commentmetaMetadate comentariiVariabil
wp_termsCategorii, tag-uri, taxonomiiZeci - sute
wp_term_taxonomyRelația termen - taxonomie= wp_terms
wp_term_relationshipsRelația post - termenVariabil
wp_linksLinkuri (depreciat)0
💡 wp_options - atenție la autoload

Tabela wp_options are o coloană autoload. Toate opțiunile cu autoload='yes' sunt încărcate la FIECARE request. Pluginurile prost scrise stochează date mari cu autoload='yes', încetinind site-ul. Verificați: SELECT SUM(LENGTH(option_value)) FROM wp_options WHERE autoload='yes'; - ar trebui să fie sub 1 MB.

WordPress Coding Standards

WordPress are standarde de cod proprii care diferă de PSR (standardele PHP general acceptate):

Diferențe cheie:

  • Indentare: TAB-uri (nu spații) pentru PHP
  • Naming: funcții și variabile cu underscore (snake_case): my_function_name
  • Clase: cu underscore și litere mari: class My_Custom_Class
  • Constante: toate cu majuscule: MY_CONSTANT
  • Hooks: numele cu underscore: my_plugin_action_name
  • Prefix: toate funcțiile, clasele și hook-urile cu prefix unic al pluginului/temei

✓ WordPress Style

function goai_get_custom_posts( $args = array() ) {
$defaults = array(
'post_type'   => 'portfolio',
'numberposts' => 10,
);
$args = wp_parse_args( $args, $defaults );
return get_posts( $args );
}
✗ PSR Style (incorect în WP)
function getCustomPosts($args = []) {
$defaults = [
'post_type' => 'portfolio',
'numberposts' => 10,
];
$args = wp_parse_args($args, $defaults);
return get_posts($args);
}
02

wp-config.php - configurare avansată

Constante esențiale

wp-config.php este fișierul de configurare principal al WordPress. Pe lângă credențialele bazei de date, puteți adăuga zeci de constante care controlează comportamentul WordPress.

Securitate:


// Dezactivare editor de fișiere din admin (previne editarea temelor/pluginurilor)
define( 'DISALLOW_FILE_EDIT', true );

// Dezactivare instalare/actualizare teme și pluginuri din admin
define( 'DISALLOW_FILE_MODS', true );

// Forțare SSL pentru admin
define( 'FORCE_SSL_ADMIN', true );

// Chei de securitate (generați unice de la api.wordpress.org/secret-key)
define( 'AUTH_KEY',         'valoare-unică-aici' );
define( 'SECURE_AUTH_KEY',  'valoare-unică-aici' );
define( 'LOGGED_IN_KEY',    'valoare-unică-aici' );
define( 'NONCE_KEY',        'valoare-unică-aici' );
define( 'AUTH_SALT',        'valoare-unică-aici' );
define( 'SECURE_AUTH_SALT', 'valoare-unică-aici' );
define( 'LOGGED_IN_SALT',   'valoare-unică-aici' );
define( 'NONCE_SALT',       'valoare-unică-aici' );

// Prefix tabele (schimbat din wp_ implicit)
$table_prefix = 'goai_';

// Blocare accesul extern la cron
define( 'DISALLOW_UNFILTERED_HTML', true );

Performanță:


// Dezactivare WP-Cron (folosiți cron real din cPanel)
define( 'DISABLE_WP_CRON', true );

// Limita revizii per post (implicit: nelimitat!)
define( 'WP_POST_REVISIONS', 5 );

// Interval auto-save (implicit: 60 secunde)
define( 'AUTOSAVE_INTERVAL', 120 );

// Interval golire coș (implicit: 30 zile)
define( 'EMPTY_TRASH_DAYS', 14 );

// Limita memorie PHP pentru WordPress
define( 'WP_MEMORY_LIMIT', '256M' );
define( 'WP_MAX_MEMORY_LIMIT', '512M' ); // pentru admin

// Cache (pentru pluginuri de object cache)
define( 'WP_CACHE', true );

// Concatenare scripturi admin (reduce requests)
define( 'CONCATENATE_SCRIPTS', true );

Debug (doar pe medii de dezvoltare!):


// Activare debug mode
define( 'WP_DEBUG', true );

// Salvare erori în fișier (wp-content/debug.log)
define( 'WP_DEBUG_LOG', true );

// NU afișa erorile pe ecran (pe producție: ÎNTOTDEAUNA false)
define( 'WP_DEBUG_DISPLAY', false );

// Folosire versiuni necompresate ale CSS/JS core
define( 'SCRIPT_DEBUG', true );

// Salvare query-uri pentru analiză
define( 'SAVEQUERIES', true );
⚠️ Debug pe producție

Nu lăsați NICIODATĂ WP_DEBUG = true pe producție! Erorile PHP pot dezvălui căi de fișiere, credențiale și structura internă a site-ului. Pe producție: WP_DEBUG = false, WP_DEBUG_DISPLAY = false.

Constante utile diverse:


// URL-uri și căi custom
define( 'WP_HOME', 'https://goai.ro' );
define( 'WP_SITEURL', 'https://goai.ro' );
define( 'WP_CONTENT_DIR', '/home/user/public_html/wp-content' );
define( 'WP_CONTENT_URL', 'https://goai.ro/wp-content' );

// Director uploads custom
define( 'UPLOADS', 'wp-content/uploads' );

// Activare Multisite
define( 'WP_ALLOW_MULTISITE', true );

// Dezactivare actualizări automate core
define( 'WP_AUTO_UPDATE_CORE', 'minor' ); // doar minor updates

// Dezactivare XML-RPC (securitate)
// Se face prin .htaccess sau plugin, nu din wp-config
03

Dezvoltare teme custom

Template Hierarchy

Template Hierarchy este sistemul prin care WordPress determină ce fișier template să folosească pentru fiecare tip de pagină. Înțelegerea acestei ierarhii este esențială pentru dezvoltarea temelor.

Ierarhia simplificată:


Pagina de start:
front-page.php → home.php → index.php

Articol singular:
single-{post-type}-{slug}.php → single-{post-type}.php → single.php → singular.php → index.php

Pagină:
{template-custom}.php → page-{slug}.php → page-{id}.php → page.php → singular.php → index.php

Categorie:
category-{slug}.php → category-{id}.php → category.php → archive.php → index.php

Tag:
tag-{slug}.php → tag-{id}.php → tag.php → archive.php → index.php

Taxonomie custom:
taxonomy-{taxonomy}-{term}.php → taxonomy-{taxonomy}.php → taxonomy.php → archive.php → index.php

Autor:
author-{nicename}.php → author-{id}.php → author.php → archive.php → index.php

Arhivă dată:
date.php → archive.php → index.php

Căutare:
search.php → index.php

404:
404.php → index.php

Atașament:
{mime-type}.php → attachment.php → single-attachment.php → single.php → index.php

Fișierele obligatorii ale unei teme

FișierObligatoriu?Funcție
style.cssDaStylesheet principal + meta informații temă (Theme Name, Author etc.)
index.phpDaTemplate fallback (ultimul din ierarhie)
functions.phpRecomandatFuncționalități temă (hooks, meniuri, widget-uri)
header.phpRecomandatAntet HTML (<head>, navigare)
footer.phpRecomandatFooter (scripturi, copyright)
sidebar.phpOpționalSidebar cu widget-uri
screenshot.pngRecomandatPreview în admin (1200×900 px)

Child Themes (teme copil)

Un child theme moștenește funcționalitățile și stilurile temei părinte, permițând personalizări fără a modifica tema originală.

Structura minimă child theme:


tema-copil/
├── style.css          ← Obligatoriu: meta + stiluri custom
├── functions.php      ← Obligatoriu: enqueue stiluri părinte
└── template-parts/    ← Opțional: override template-uri specifice

style.css - child theme:


/*
Theme Name:   Tema GOAI Child
Template:     tema-parinte
Description:  Child theme pentru Tema Părinte
Author:       GOAI
Version:      1.0.0
*/

/* Stiluri custom aici */

functions.php - child theme:


<?php
// Încărcare stiluri tema părinte + child
function goai_child_enqueue_styles() {
wp_enqueue_style(
'parent-style',
get_template_directory_uri() . '/style.css'
);
wp_enqueue_style(
'child-style',
get_stylesheet_directory_uri() . '/style.css',
array( 'parent-style' ),
wp_get_theme()->get( 'Version' )
);
}
add_action( 'wp_enqueue_scripts', 'goai_child_enqueue_styles' );

Full Site Editing (FSE)

Full Site Editing este paradigma modernă în WordPress (de la 5.9+). Permite editarea întregului site din editorul de blocuri, inclusiv header, footer și template-uri.

Structura unui block theme:


tema-block/
├── style.css
├── functions.php
├── theme.json            ← Configurare globală (culori, fonturi, spacing)
├── templates/            ← Template-uri HTML (blocuri)
│   ├── index.html
│   ├── single.html
│   ├── page.html
│   ├── archive.html
│   ├── 404.html
│   └── search.html
├── parts/                ← Părți reutilizabile
│   ├── header.html
│   ├── footer.html
│   └── sidebar.html
└── patterns/             ← Block patterns predefinite
└── hero.php

Exemplu theme.json:


{
"$schema": "https://schemas.wp.org/trunk/theme.json",
"version": 3,
"settings": {
"color": {
"palette": [
{ "slug": "primary", "color": "#ccac65", "name": "Gold" },
{ "slug": "secondary", "color": "#01ce4c", "name": "Green" },
{ "slug": "dark", "color": "#1b2028", "name": "Dark" }
]
},
"typography": {
"fontFamilies": [
{
"fontFamily": "'Segoe UI', sans-serif",
"slug": "primary",
"name": "Primary"
}
],
"fontSizes": [
{ "slug": "small", "size": "0.875rem", "name": "Small" },
{ "slug": "medium", "size": "1rem", "name": "Medium" },
{ "slug": "large", "size": "1.5rem", "name": "Large" }
]
},
"layout": { "contentSize": "800px", "wideSize": "1200px" }
}
}

📌 Classic vs Block Themes

Classic themes (PHP-based) sunt încă funcționale și larg utilizate. Block themes (FSE) sunt viitorul WordPress. Pentru proiecte noi, recomandăm block themes dacă clientul dorește control maxim din admin fără cod.

04

Dezvoltare pluginuri

Structura unui plugin

Un plugin WordPress este un pachet de cod PHP care extinde funcționalitățile WordPress fără a modifica core-ul.

Structura minimă:


goai-plugin/
├── goai-plugin.php        ← Fișierul principal (header obligatoriu)
├── readme.txt             ← Descriere plugin (format WordPress.org)
├── includes/              ← Clase și funcții PHP
│   ├── class-main.php
│   ├── class-admin.php
│   └── class-public.php
├── admin/                 ← Fișiere pentru interfața admin
│   ├── css/
│   ├── js/
│   └── views/
├── public/                ← Fișiere pentru frontend
│   ├── css/
│   └── js/
├── languages/             ← Fișiere traducere (.pot, .po, .mo)
├── templates/             ← Template-uri override-able
└── assets/                ← Imagini, fonturi etc.

Header-ul obligatoriu al pluginului:


<?php
/**
* Plugin Name:       GOAI Custom Plugin
* Plugin URI:        https://goai.ro/plugin
* Description:       Descrierea pluginului dvs.
* Version:           1.0.0
* Requires at least: 6.0
* Requires PHP:      8.0
* Author:            Dorel Tănase - GOAI
* Author URI:        https://goai.ro
* License:           GPL v2 or later
* Text Domain:       goai-plugin
* Domain Path:       /languages
*/

// Prevenire acces direct
if ( ! defined( 'ABSPATH' ) ) {
exit;
}

// Constante plugin
define( 'GOAI_PLUGIN_VERSION', '1.0.0' );
define( 'GOAI_PLUGIN_PATH', plugin_dir_path( __FILE__ ) );
define( 'GOAI_PLUGIN_URL', plugin_dir_url( __FILE__ ) );

Hooks de activare/dezactivare/ștergere


// La activare - creare tabele, opțiuni default
register_activation_hook( __FILE__, 'goai_plugin_activate' );
function goai_plugin_activate() {
// Creare tabel custom
global $wpdb;
$charset_collate = $wpdb->get_charset_collate();
$table = $wpdb->prefix . 'goai_data';

$sql = "CREATE TABLE $table (
id bigint(20) NOT NULL AUTO_INCREMENT,
title varchar(255) NOT NULL,
created_at datetime DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (id)
) $charset_collate;";

require_once ABSPATH . 'wp-admin/includes/upgrade.php';
dbDelta( $sql );

// Setare opțiuni default
add_option( 'goai_plugin_version', GOAI_PLUGIN_VERSION );
add_option( 'goai_plugin_settings', array( 'enabled' => true ) );
}

// La dezactivare - curățare temporară
register_deactivation_hook( __FILE__, 'goai_plugin_deactivate' );
function goai_plugin_deactivate() {
// Curățare cron jobs etc.
wp_clear_scheduled_hook( 'goai_daily_event' );
}

// La ștergere (uninstall.php sau hook) - curățare completă
register_uninstall_hook( __FILE__, 'goai_plugin_uninstall' );
function goai_plugin_uninstall() {
global $wpdb;
$wpdb->query( "DROP TABLE IF EXISTS {$wpdb->prefix}goai_data" );
delete_option( 'goai_plugin_version' );
delete_option( 'goai_plugin_settings' );
}

Pagini de setări în admin


// Adăugare meniu în admin
function goai_admin_menu() {
add_menu_page(
'GOAI Settings',           // titlu pagină
'GOAI Plugin',             // titlu meniu
'manage_options',          // capabilitate necesară
'goai-settings',           // slug pagină
'goai_settings_page',      // funcția de render
'dashicons-admin-generic', // icon
80                         // poziție în meniu
);

add_submenu_page(
'goai-settings',           // parent slug
'General Settings',        // titlu pagină
'General',                 // titlu submeniu
'manage_options',
'goai-settings',
'goai_settings_page'
);
}
add_action( 'admin_menu', 'goai_admin_menu' );

// Render pagina de setări
function goai_settings_page() {
if ( ! current_user_can( 'manage_options' ) ) {
return;
}
?>
<div class="wrap">
<h1><?php echo esc_html( get_admin_page_title() ); ?></h1>
<form action="options.php" method="post">
<?php
settings_fields( 'goai_settings_group' );
do_settings_sections( 'goai-settings' );
submit_button();
?>
</form>
</div>
<?php
}

Must-Use Plugins (mu-plugins)

Must-Use Plugins sunt pluginuri plasate în directorul wp-content/mu-plugins/ care sunt încărcate automat, fără a necesita activare. Nu pot fi dezactivate din admin.

Cazuri de utilizare mu-plugins:

  • Funcționalități critice care nu trebuie dezactivate accidental
  • Custom code snippets (în loc de functions.php al temei)
  • Configurări specifice mediului (staging vs producție)
  • Dezactivare funcționalități WordPress (XML-RPC, REST API parțial)
💡 mu-plugins vs functions.php

Codul custom care nu este legat de temă (dezactivare XML-RPC, custom post types, snippets de securitate) ar trebui pus într-un mu-plugin, nu în functions.php. Astfel, dacă schimbați tema, funcționalitățile rămân intacte.

05

Hooks: Actions și Filters

Ce sunt Hooks?

Sistemul de hooks este inima arhitecturii WordPress. Permite inserarea de cod custom în puncte specifice ale execuției WordPress, fără a modifica fișierele core.

Două tipuri de hooks:

ActionsFilters
Execută o acțiune (inserare, modificare, ștergere)Modifică o valoare și o returnează
Nu returnează nimicTREBUIE să returneze valoarea (modificată sau nu)
add_action() / do_action()add_filter() / apply_filters()
Ex: wp_head, init, save_postEx: the_content, the_title, body_class

Actions - exemple practice


// Adăugare cod în <head>
function goai_add_meta_tags() {
echo '<meta name="author" content="GOAI">' . "\n";
echo '<meta name="theme-color" content="#1b2028">' . "\n";
}
add_action( 'wp_head', 'goai_add_meta_tags', 5 ); // prioritate 5 (devreme)

// Acțiune la salvarea unui post
function goai_on_save_post( $post_id, $post, $update ) {
// Ignoră auto-save
if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE ) return;
// Ignoră reviziile
if ( wp_is_post_revision( $post_id ) ) return;
// Doar pentru articole
if ( $post->post_type !== 'post' ) return;

// Logica custom
update_post_meta( $post_id, '_goai_last_edited', current_time( 'mysql' ) );
}
add_action( 'save_post', 'goai_on_save_post', 10, 3 );

// Adăugare funcționalitate la init
function goai_custom_init() {
// Înregistrare Custom Post Type
// Înregistrare Taxonomie
// Alte inițializări
}
add_action( 'init', 'goai_custom_init' );

Filters - exemple practice


// Modificare conținut articol (adăugare text la final)
function goai_append_signature( $content ) {
if ( is_single() && in_the_loop() && is_main_query() ) {
$signature = '<p class="author-sig">Articol scris de GOAI.</p>';
$content .= $signature;
}
return $content; // TREBUIE să returnați!
}
add_filter( 'the_content', 'goai_append_signature' );

// Modificare titlu
function goai_modify_title( $title, $id = null ) {
if ( is_admin() ) return $title;
return $title . ' - GOAI';
}
add_filter( 'the_title', 'goai_modify_title', 10, 2 );

// Adăugare clase pe <body>
function goai_body_classes( $classes ) {
if ( is_front_page() ) {
$classes[] = 'goai-homepage';
}
$classes[] = 'goai-theme';
return $classes;
}
add_filter( 'body_class', 'goai_body_classes' );

// Modificare excerpt length
function goai_excerpt_length( $length ) {
return 30; // 30 cuvinte
}
add_filter( 'excerpt_length', 'goai_excerpt_length' );

// Personalizare "Read more" link
function goai_read_more_link() {
return '<a href="' . get_permalink() . '" class="read-more">Citește mai mult →</a>';
}
add_filter( 'the_content_more_link', 'goai_read_more_link' );

Hooks frecvent utilizate

HookTipCând se execută
initActionDupă încărcare WordPress, înainte de output
wp_enqueue_scriptsActionMomentul corect de adăugare CSS/JS
wp_headActionÎn <head> (meta, scripturi)
wp_footerActionÎnainte de </body>
admin_initActionLa inițializarea admin-ului
admin_menuActionConstruire meniu admin
save_postActionLa salvarea unui post
template_redirectActionÎnainte de încărcare template
the_contentFilterFiltrare conținut articol
the_titleFilterFiltrare titlu
body_classFilterClase CSS pe <body>
wp_nav_menu_itemsFilterModificare meniu navigare
login_redirectFilterRedirecționare după login
upload_mimesFilterTipuri de fișiere permise upload

Priorități și parametri


// Sintaxă completă
add_action( 'hook_name', 'callback_function', $priority, $accepted_args );
add_filter( 'hook_name', 'callback_function', $priority, $accepted_args );

// $priority: implicit 10. Valoare mai mică = execuție mai devreme
// $accepted_args: numărul de parametri pe care funcția îi primește

// Exemplu cu prioritate
add_action( 'wp_head', 'critical_css', 1 );    // primul
add_action( 'wp_head', 'analytics_code', 99 );  // ultimul

// Eliminare hook
remove_action( 'wp_head', 'wp_generator' );     // elimină versiunea WP din head
remove_action( 'wp_head', 'wlwmanifest_link' ); // elimină Windows Live Writer
remove_action( 'wp_head', 'rsd_link' );         // elimină Really Simple Discovery
💡 Regula de aur pentru Filters

Un filter TREBUIE ÎNTOTDEAUNA să returneze o valoare. Dacă uitați return, conținutul va fi gol. Aceasta este cea mai frecventă greșeală la lucrul cu filters.

06

Custom Post Types și Taxonomii

Ce sunt Custom Post Types (CPT)?

WordPress vine implicit cu tipurile: post, page, attachment, revision, nav_menu_item. Custom Post Types vă permit să creați tipuri de conținut personalizate (portofoliu, produse, testimoniale, echipă etc.).

Înregistrare CPT:


function goai_register_portfolio_cpt() {
$labels = array(
'name'               => 'Portofoliu',
'singular_name'      => 'Proiect',
'menu_name'          => 'Portofoliu',
'add_new'            => 'Adaugă proiect',
'add_new_item'       => 'Adaugă proiect nou',
'edit_item'          => 'Editează proiect',
'new_item'           => 'Proiect nou',
'view_item'          => 'Vezi proiect',
'search_items'       => 'Caută proiecte',
'not_found'          => 'Nu s-au găsit proiecte',
'not_found_in_trash' => 'Nu sunt proiecte în coș',
);

$args = array(
'labels'             => $labels,
'public'             => true,
'publicly_queryable' => true,
'show_ui'            => true,
'show_in_menu'       => true,
'show_in_rest'       => true, // Necesar pentru Gutenberg!
'query_var'          => true,
'rewrite'            => array( 'slug' => 'portofoliu' ),
'capability_type'    => 'post',
'has_archive'        => true,
'hierarchical'       => false,
'menu_position'      => 20,
'menu_icon'          => 'dashicons-portfolio',
'supports'           => array(
'title', 'editor', 'thumbnail', 'excerpt', 'custom-fields'
),
);

register_post_type( 'portfolio', $args );
}
add_action( 'init', 'goai_register_portfolio_cpt' );

Custom Taxonomies

Taxonomiile custom permit clasificarea CPT-urilor (similar cu categoriile și tag-urile pentru articole).


function goai_register_portfolio_taxonomy() {
$labels = array(
'name'          => 'Categorii proiecte',
'singular_name' => 'Categorie proiect',
'search_items'  => 'Caută categorii',
'all_items'     => 'Toate categoriile',
'parent_item'   => 'Categorie părinte',
'edit_item'     => 'Editează categorie',
'add_new_item'  => 'Adaugă categorie',
'menu_name'     => 'Categorii',
);

register_taxonomy( 'portfolio_category', 'portfolio', array(
'labels'            => $labels,
'hierarchical'      => true,  // true = categorii, false = tag-uri
'public'            => true,
'show_in_rest'      => true,
'show_admin_column' => true,
'rewrite'           => array( 'slug' => 'categorie-proiect' ),
) );
}
add_action( 'init', 'goai_register_portfolio_taxonomy' );

Custom Meta Boxes

Meta boxes adaugă câmpuri custom pe ecranul de editare al unui post/CPT.


// Adăugare meta box
function goai_add_project_meta_box() {
add_meta_box(
'goai_project_details',      // ID
'Detalii proiect',           // Titlu
'goai_project_meta_callback', // Funcție render
'portfolio',                  // Post type
'normal',                     // Context (normal, side, advanced)
'high'                        // Prioritate
);
}
add_action( 'add_meta_boxes', 'goai_add_project_meta_box' );

// Render meta box
function goai_project_meta_callback( $post ) {
wp_nonce_field( 'goai_project_nonce_action', 'goai_project_nonce' );

$client = get_post_meta( $post->ID, '_goai_client', true );
$url    = get_post_meta( $post->ID, '_goai_project_url', true );
$year   = get_post_meta( $post->ID, '_goai_year', true );
?>
<p>
<label for="goai_client">Client:</label>
<input type="text" id="goai_client" name="goai_client"
value="<?php echo esc_attr( $client ); ?>" class="widefat">
</p>
<p>
<label for="goai_project_url">URL proiect:</label>
<input type="url" id="goai_project_url" name="goai_project_url"
value="<?php echo esc_url( $url ); ?>" class="widefat">
</p>
<p>
<label for="goai_year">An:</label>
<input type="number" id="goai_year" name="goai_year"
value="<?php echo esc_attr( $year ); ?>" min="2000" max="2030">
</p>
<?php
}

// Salvare meta data
function goai_save_project_meta( $post_id ) {
// Verificări securitate
if ( ! isset( $_POST['goai_project_nonce'] ) ) return;
if ( ! wp_verify_nonce( $_POST['goai_project_nonce'], 'goai_project_nonce_action' ) ) return;
if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE ) return;
if ( ! current_user_can( 'edit_post', $post_id ) ) return;

// Sanitizare și salvare
if ( isset( $_POST['goai_client'] ) ) {
update_post_meta( $post_id, '_goai_client', sanitize_text_field( $_POST['goai_client'] ) );
}
if ( isset( $_POST['goai_project_url'] ) ) {
update_post_meta( $post_id, '_goai_project_url', esc_url_raw( $_POST['goai_project_url'] ) );
}
if ( isset( $_POST['goai_year'] ) ) {
update_post_meta( $post_id, '_goai_year', absint( $_POST['goai_year'] ) );
}
}
add_action( 'save_post_portfolio', 'goai_save_project_meta' );
💡 Alternative moderne

Pentru meta boxes complexe, pluginul Advanced Custom Fields (ACF) este standard-ul industriei. Oferă interfață drag-and-drop pentru câmpuri custom fără cod. Versiunea Pro include repeater fields, flexible content, gallery etc.

07

REST API WordPress

Ce este REST API?

REST API WordPress permite interacțiunea cu datele WordPress prin cereri HTTP standard (GET, POST, PUT, DELETE). Este fundamentul aplicațiilor WordPress headless, mobile apps și integrărilor cu servicii externe.

URL de bază:

https://domeniu.ro/wp-json/wp/v2/

Endpoint-uri implicite:

EndpointMetodăDescriere
/wp/v2/postsGETLista de articole
/wp/v2/posts/{id}GETUn articol specific
/wp/v2/postsPOSTCreare articol nou
/wp/v2/posts/{id}PUT/PATCHActualizare articol
/wp/v2/posts/{id}DELETEȘtergere articol
/wp/v2/pagesGETLista de pagini
/wp/v2/categoriesGETLista de categorii
/wp/v2/tagsGETLista de tag-uri
/wp/v2/mediaGET/POSTFișiere media
/wp/v2/usersGETLista utilizatori

Parametri de filtrare:


# Ultimele 5 articole
GET /wp/v2/posts?per_page=5&orderby=date&order=desc

# Articole dintr-o categorie specifică
GET /wp/v2/posts?categories=15

# Căutare
GET /wp/v2/posts?search=wordpress

# Articole cu câmpuri specifice
GET /wp/v2/posts?_fields=id,title,excerpt,link

# Paginare
GET /wp/v2/posts?page=2&per_page=10

Creare endpoint-uri custom


// Înregistrare route custom
function goai_register_api_routes() {
register_rest_route( 'goai/v1', '/projects', array(
'methods'             => 'GET',
'callback'            => 'goai_get_projects',
'permission_callback' => '__return_true', // public
'args'                => array(
'category' => array(
'required' => false,
'type'     => 'string',
'sanitize_callback' => 'sanitize_text_field',
),
'limit' => array(
'required' => false,
'type'     => 'integer',
'default'  => 10,
),
),
) );

register_rest_route( 'goai/v1', '/projects/(?P<id>\d+)', array(
'methods'             => 'GET',
'callback'            => 'goai_get_single_project',
'permission_callback' => '__return_true',
) );

// Endpoint cu autentificare
register_rest_route( 'goai/v1', '/projects', array(
'methods'             => 'POST',
'callback'            => 'goai_create_project',
'permission_callback' => function() {
return current_user_can( 'edit_posts' );
},
) );
}
add_action( 'rest_api_init', 'goai_register_api_routes' );

// Callback GET
function goai_get_projects( $request ) {
$args = array(
'post_type'      => 'portfolio',
'posts_per_page' => $request->get_param( 'limit' ),
'post_status'    => 'publish',
);

$category = $request->get_param( 'category' );
if ( $category ) {
$args['tax_query'] = array( array(
'taxonomy' => 'portfolio_category',
'field'    => 'slug',
'terms'    => $category,
) );
}

$posts = get_posts( $args );
$data  = array();

foreach ( $posts as $post ) {
$data[] = array(
'id'        => $post->ID,
'title'     => $post->post_title,
'excerpt'   => wp_strip_all_tags( $post->post_excerpt ),
'link'      => get_permalink( $post->ID ),
'thumbnail' => get_the_post_thumbnail_url( $post->ID, 'medium' ),
'client'    => get_post_meta( $post->ID, '_goai_client', true ),
);
}

return new WP_REST_Response( $data, 200 );
}

Autentificare REST API

MetodăUtilizareSecuritate
Cookie AuthLogat în WordPress (admin)Nonce-based, implicit
Application PasswordsAplicații externe, scripturiUsername + password app
JWT (plugin)Aplicații mobile, SPAToken Bearer
OAuth 2.0 (plugin)Integrări terțeStandard OAuth
⚠️ Securizare REST API

Implicit, REST API expune informații despre utilizatori (GET /wp/v2/users). Dezactivați endpoint-urile nefolosite sau restricționați accesul. Adăugați în functions.php/mu-plugin codul de restricționare pentru producție.

08

Baza de date și WP_Query

WP_Query - query-uri avansate

WP_Query este clasa principală pentru interogarea bazei de date WordPress. Permite căutarea, filtrarea și sortarea oricărui tip de conținut.

Structura de bază:


$args = array(
'post_type'      => 'post',
'posts_per_page' => 10,
'orderby'        => 'date',
'order'          => 'DESC',
'post_status'    => 'publish',
);

$query = new WP_Query( $args );

if ( $query->have_posts() ) :
while ( $query->have_posts() ) : $query->the_post();
the_title( '<h2>', '</h2>' );
the_excerpt();
endwhile;
wp_reset_postdata(); // IMPORTANT: resetare query!
else :
echo '<p>Nu s-au găsit rezultate.</p>';
endif;

Query-uri avansate cu meta:


// Proiecte cu client specific, sortate după an
$args = array(
'post_type'  => 'portfolio',
'meta_query' => array(
'relation' => 'AND',
'client_clause' => array(
'key'     => '_goai_client',
'value'   => 'GOAI',
'compare' => '=',
),
'year_clause' => array(
'key'     => '_goai_year',
'value'   => 2024,
'compare' => '>=',
'type'    => 'NUMERIC',
),
),
'orderby' => array(
'year_clause' => 'DESC',
'title'       => 'ASC',
),
);

Tax Query (filtrare pe taxonomii):


$args = array(
'post_type' => 'portfolio',
'tax_query' => array(
'relation' => 'AND',
array(
'taxonomy' => 'portfolio_category',
'field'    => 'slug',
'terms'    => array( 'web-design', 'branding' ),
'operator' => 'IN',
),
array(
'taxonomy' => 'portfolio_tag',
'field'    => 'slug',
'terms'    => 'wordpress',
),
),
);

$wpdb - query-uri directe

Pentru query-uri complexe care nu pot fi realizate cu WP_Query, folosiți $wpdb:


global $wpdb;

// SELECT cu prepare (previne SQL injection!)
$results = $wpdb->get_results(
$wpdb->prepare(
"SELECT p.ID, p.post_title, pm.meta_value as client
FROM {$wpdb->posts} p
INNER JOIN {$wpdb->postmeta} pm ON p.ID = pm.post_id
WHERE p.post_type = %s
AND p.post_status = %s
AND pm.meta_key = %s
ORDER BY p.post_date DESC
LIMIT %d",
'portfolio', 'publish', '_goai_client', 20
)
);

// INSERT
$wpdb->insert(
$wpdb->prefix . 'goai_data',
array( 'title' => 'Proiect nou', 'created_at' => current_time( 'mysql' ) ),
array( '%s', '%s' )
);

// UPDATE
$wpdb->update(
$wpdb->prefix . 'goai_data',
array( 'title' => 'Titlu actualizat' ),   // date
array( 'id' => 5 ),                         // where
array( '%s' ),                               // format date
array( '%d' )                                // format where
);
⚠️ ÎNTOTDEAUNA $wpdb->prepare()!

NU concatenați NICIODATĂ variabile direct în query-uri SQL. Folosiți $wpdb->prepare() cu placeholdere (%s pentru string, %d pentru integer, %f pentru float). Altfel, sunteți vulnerabili la SQL injection.

Transients - cache temporar

Transients sunt un sistem de cache incorporat în WordPress. Stochează date temporar cu un timp de expirare.


// Setare transient (cache pentru 1 oră)
function goai_get_cached_projects() {
$data = get_transient( 'goai_projects_cache' );

if ( false === $data ) {
// Cache expirat sau inexistent - interogăm BD
$query = new WP_Query( array(
'post_type'      => 'portfolio',
'posts_per_page' => 50,
) );

$data = array();
foreach ( $query->posts as $post ) {
$data[] = array(
'id'    => $post->ID,
'title' => $post->post_title,
);
}

// Salvare în cache pentru 1 oră (3600 secunde)
set_transient( 'goai_projects_cache', $data, HOUR_IN_SECONDS );
}

return $data;
}

// Invalidare cache la modificare proiect
function goai_clear_projects_cache( $post_id ) {
if ( get_post_type( $post_id ) === 'portfolio' ) {
delete_transient( 'goai_projects_cache' );
}
}
add_action( 'save_post', 'goai_clear_projects_cache' );
09

Securitate WordPress avansată

Principalele vulnerabilități WordPress

VulnerabilitateDescriereRisc
SQL InjectionInjectare cod SQL prin input-uriCritic
XSS (Cross-Site Scripting)Injectare JavaScript malițiosRidicat
CSRF (Cross-Site Request Forgery)Acțiuni neautorizateRidicat
Brute ForceGhicirea parolei prin încercări repetateMediu-ridicat
File InclusionIncluderea fișierelor neautorizateCritic
Pluginuri/teme vulnerabileCod terț cu breșe de securitateRidicat
BackdoorsCod ascuns pentru acces neautorizatCritic

Hardening WordPress

1. Funcții de sanitizare și escapare:


// SANITIZARE INPUT (la primire date)
sanitize_text_field( $input );      // Text simplu
sanitize_email( $email );            // Email
sanitize_url( $url );                // URL
absint( $number );                   // Număr pozitiv
wp_kses_post( $html );              // HTML permis (ca în articole)
sanitize_file_name( $filename );     // Nume fișier

// ESCAPARE OUTPUT (la afișare date)
esc_html( $text );       // Escapare HTML (în text)
esc_attr( $attribute );  // Escapare atribut HTML
esc_url( $url );         // Escapare URL
esc_js( $string );       // Escapare JavaScript
wp_kses( $html, $tags ); // Filtrare HTML cu tag-uri permise

2. Nonces (protecție CSRF):


// Generare nonce în formular
wp_nonce_field( 'goai_action_name', 'goai_nonce_field' );

// Verificare nonce la procesare
if ( ! wp_verify_nonce( $_POST['goai_nonce_field'], 'goai_action_name' ) ) {
wp_die( 'Verificare securitate eșuată.' );
}

// Nonce în URL
$url = wp_nonce_url( admin_url( 'admin.php?action=delete&id=5' ), 'goai_delete_5' );

// Verificare nonce din URL
check_admin_referer( 'goai_delete_5' );

3. Hardening prin cod (mu-plugin recomandat):


// Dezactivare XML-RPC
add_filter( 'xmlrpc_enabled', '__return_false' );

// Ascundere versiune WordPress
remove_action( 'wp_head', 'wp_generator' );

// Dezactivare REST API pentru utilizatori neautentificați
function goai_restrict_rest_api( $result ) {
if ( ! is_user_logged_in() ) {
// Permit doar endpoint-urile publice necesare
$allowed = array( '/wp/v2/posts', '/wp/v2/pages', '/wp/v2/categories' );
$route   = $GLOBALS['wp']->query_vars['rest_route'] ?? '';

foreach ( $allowed as $endpoint ) {
if ( strpos( $route, $endpoint ) === 0 ) {
return $result;
}
}
return new WP_Error( 'rest_forbidden', 'Acces interzis.', array( 'status' => 403 ) );
}
return $result;
}
add_filter( 'rest_authentication_errors', 'goai_restrict_rest_api' );

// Dezactivare Directory Browsing (backup .htaccess)
// Options -Indexes (în .htaccess)

// Protecție wp-config.php (.htaccess)
// <files wp-config.php>
//   order allow,deny
//   deny from all
// </files>

// Limitare încercări login
function goai_limit_login_attempts( $user, $username, $password ) {
$ip = $_SERVER['REMOTE_ADDR'];
$transient = 'goai_login_attempts_' . md5( $ip );
$attempts  = get_transient( $transient );

if ( $attempts >= 5 ) {
return new WP_Error( 'too_many_attempts', 'Prea multe încercări. Reveniți în 15 minute.' );
}

return $user;
}
add_filter( 'authenticate', 'goai_limit_login_attempts', 30, 3 );

Pluginuri de securitate recomandate

PluginFuncții principalePreț
WordfenceFirewall, scanare malware, brute force protectionGratuit / $119/an
Sucuri SecurityScanare, firewall cloud, CDN, cleanupDe la $199/an
iThemes SecurityHardening, 2FA, database backupGratuit / $99/an
All In One WP SecurityHardening, firewall basic, user securityGratuit

📌 Regula securității WordPress

95% din hack-urile WordPress sunt cauzate de: pluginuri/teme neactualizate, parole slabe, sau pluginuri din surse nesigure. Mențineți totul actualizat, folosiți parole puternice și instalați doar din surse de încredere (wordpress.org sau developeri verificați).

10

Performanță și optimizare

Core Web Vitals

Core Web Vitals sunt metricile Google care măsoară experiența utilizatorului și influențează clasamentul SEO.

MetricăCe măsoarăBunNecesită îmbunătățireSlab
LCP (Largest Contentful Paint)Viteza de încărcare vizuală< 2.5s2.5 - 4s> 4s
INP (Interaction to Next Paint)Responsivitatea la interacțiuni< 200ms200 - 500ms> 500ms
CLS (Cumulative Layout Shift)Stabilitatea vizuală< 0.10.1 - 0.25> 0.25

Strategii de caching

1. Page Cache:

Salvează pagina HTML completă și o servește direct, fără execuție PHP/MySQL. Efectul este dramatic - de la 2-3 secunde la sub 200ms.

2. Object Cache (Redis/Memcached):

Cachează rezultatele query-urilor MySQL în memorie. Reduce semnificativ încărcarea bazei de date.

3. Browser Cache:


# .htaccess - browser caching
<IfModule mod_expires.c>
ExpiresActive On
ExpiresByType image/jpg "access plus 1 year"
ExpiresByType image/jpeg "access plus 1 year"
ExpiresByType image/png "access plus 1 year"
ExpiresByType image/webp "access plus 1 year"
ExpiresByType image/svg+xml "access plus 1 year"
ExpiresByType text/css "access plus 1 month"
ExpiresByType application/javascript "access plus 1 month"
ExpiresByType application/font-woff2 "access plus 1 year"
</IfModule>

4. CDN (Content Delivery Network):

Servește resursele statice (imagini, CSS, JS) de pe servere distribuite global, aproape de vizitator.

Optimizare imagini

  • Format WebP/AVIF - 25-50% mai mici decât JPEG/PNG
  • Lazy loading - încărcare amânată (nativ: loading="lazy")
  • Dimensiuni responsive - srcset cu mai multe dimensiuni
  • Compresie - pluginuri: ShortPixel, Imagify, Smush
  • Dimensiunea corectă - nu încărcați imagini de 4000px pentru un container de 800px

Optimizare CSS/JS


// Încărcare condiționată (doar pe paginile necesare)
function goai_conditional_assets() {
// Slider JS doar pe homepage
if ( is_front_page() ) {
wp_enqueue_script( 'goai-slider', get_template_directory_uri() . '/js/slider.js' );
}

// Contact form CSS/JS doar pe pagina Contact
if ( is_page( 'contact' ) ) {
wp_enqueue_style( 'goai-contact', get_template_directory_uri() . '/css/contact.css' );
}

// Dezîncărcare plugin-uri pe pagini unde nu sunt necesare
if ( ! is_singular( 'product' ) ) {
wp_dequeue_style( 'woocommerce-general' );
}
}
add_action( 'wp_enqueue_scripts', 'goai_conditional_assets', 20 );

// Defer/Async pe scripturi
function goai_defer_scripts( $tag, $handle, $src ) {
$defer_scripts = array( 'goai-analytics', 'goai-slider' );
if ( in_array( $handle, $defer_scripts ) ) {
return str_replace( ' src', ' defer src', $tag );
}
return $tag;
}
add_filter( 'script_loader_tag', 'goai_defer_scripts', 10, 3 );

Pluginuri de performanță recomandate

PluginServerFuncții principale
LiteSpeed CacheLiteSpeedPage cache, object cache, CSS/JS optimization, image WebP, CDN
WP RocketOricePage cache, lazy load, preload, minificare, database cleanup
W3 Total CacheOricePage cache, object cache, CDN, minificare (complex)
PerfmattersOriceScript manager (dezactivare per pagină), lazy load, preload
AutoptimizeOriceCSS/JS minificare și combinare (gratuit)
💡 Database cleanup

Periodic, curățați baza de date: revizii vechi, transients expirați, comentarii spam, opțiuni autoload inutile. Plugin: WP-Optimize sau LiteSpeed Cache → Database Optimization.

11

WooCommerce avansat

Arhitectura WooCommerce

WooCommerce este cel mai popular plugin eCommerce WordPress, alimentând peste 25% din toate magazinele online. Pentru dezvoltatorii avansați, WooCommerce oferă un ecosistem extins de hooks, template override-uri și API-uri.

Hooks WooCommerce esențiale


// Adăugare conținut pe pagina de produs (după descriere scurtă)
function goai_after_short_description() {
echo '<div class="goai-badge">✓ Produs verificat GOAI</div>';
}
add_action( 'woocommerce_single_product_summary', 'goai_after_short_description', 25 );

// Modificare număr produse per pagină
add_filter( 'loop_shop_per_page', function( $cols ) { return 24; } );

// Adăugare câmp custom pe checkout
function goai_custom_checkout_field( $checkout ) {
woocommerce_form_field( 'goai_company_cui', array(
'type'        => 'text',
'class'       => array( 'form-row-wide' ),
'label'       => 'CUI (pentru factură firmă)',
'placeholder' => 'Ex: RO12345678',
'required'    => false,
), $checkout->get_value( 'goai_company_cui' ) );
}
add_action( 'woocommerce_after_order_notes', 'goai_custom_checkout_field' );

// Salvare câmp custom
function goai_save_custom_checkout_field( $order_id ) {
if ( ! empty( $_POST['goai_company_cui'] ) ) {
$order = wc_get_order( $order_id );
$order->update_meta_data( '_goai_company_cui',
sanitize_text_field( $_POST['goai_company_cui'] ) );
$order->save();
}
}
add_action( 'woocommerce_checkout_update_order_meta', 'goai_save_custom_checkout_field' );

// Redirect după adăugare în coș → direct la checkout
add_filter( 'woocommerce_add_to_cart_redirect', function() {
return wc_get_checkout_url();
} );

// Modificare text buton „Adaugă în coș"
add_filter( 'woocommerce_product_single_add_to_cart_text', function() {
return 'Cumpără acum';
} );

Template override WooCommerce

WooCommerce permite suprascrierea template-urilor prin copierea lor în tema dvs.:


# Structura template-urilor WooCommerce:
# Plugin: wp-content/plugins/woocommerce/templates/

# Override în tema dvs.:
# Tema: wp-content/themes/tema-dvs/woocommerce/

# Exemple:
# single-product.php → tema/woocommerce/single-product.php
# content-product.php → tema/woocommerce/content-product.php
# cart/cart.php → tema/woocommerce/cart/cart.php
# checkout/form-checkout.php → tema/woocommerce/checkout/form-checkout.php

WooCommerce REST API

WooCommerce extinde REST API WordPress cu endpoint-uri pentru produse, comenzi, clienți etc.:


GET  /wp-json/wc/v3/products          # Lista produse
POST /wp-json/wc/v3/products          # Creare produs
GET  /wp-json/wc/v3/orders            # Lista comenzi
PUT  /wp-json/wc/v3/orders/{id}       # Actualizare comandă
GET  /wp-json/wc/v3/customers         # Lista clienți
GET  /wp-json/wc/v3/reports/sales     # Raport vânzări

# Autentificare: Consumer Key + Consumer Secret
# Generare: WooCommerce → Settings → Advanced → REST API

📌 Performanță WooCommerce

WooCommerce poate fi lent pe magazine mari (1000+ produse). Soluții: activați HPOS (High-Performance Order Storage), folosiți object cache (Redis), dezactivați widget-urile nefolosite, și curățați periodic sesiunile expirate din wp_options.

12

Gutenberg și Block Development

Ecosistemul de blocuri

Gutenberg (editorul de blocuri) este viitorul WordPress. Dezvoltarea de blocuri custom permite crearea de componente reutilizabile vizuale pe care editorii le pot folosi fără cod.

Creare bloc custom cu @wordpress/create-block


# Generare scaffold bloc
npx @wordpress/create-block goai-custom-block --namespace goai

# Structura generată:
goai-custom-block/
├── build/               ← Fișiere compilate (auto-generate)
├── src/
│   ├── index.js         ← Punct de intrare (înregistrare bloc)
│   ├── edit.js          ← Componenta pentru editor
│   ├── save.js          ← Componenta pentru frontend
│   ├── style.scss       ← Stiluri frontend
│   └── editor.scss      ← Stiluri editor
├── goai-custom-block.php ← Înregistrare PHP
├── block.json           ← Metadate bloc
└── package.json

# Comenzi dezvoltare
npm start    # Watch mode (compilare automată la modificări)
npm run build # Build producție

block.json (configurare bloc):


{
"$schema": "https://schemas.wp.org/trunk/block.json",
"apiVersion": 3,
"name": "goai/testimonial",
"version": "1.0.0",
"title": "Testimonial GOAI",
"category": "goai-blocks",
"icon": "format-quote",
"description": "Bloc pentru afișarea testimonialelor clienților.",
"keywords": [ "testimonial", "recenzie", "client" ],
"supports": {
"html": false,
"color": { "background": true, "text": true },
"spacing": { "margin": true, "padding": true },
"align": [ "wide", "full" ]
},
"attributes": {
"quote": { "type": "string", "default": "" },
"author": { "type": "string", "default": "" },
"role": { "type": "string", "default": "" },
"rating": { "type": "number", "default": 5 }
},
"editorScript": "file:./index.js",
"editorStyle": "file:./index.css",
"style": "file:./style-index.css"
}

Block Patterns

Block Patterns sunt combinații predefinite de blocuri pe care utilizatorii le pot insera cu un click:


function goai_register_patterns() {
register_block_pattern(
'goai/hero-section',
array(
'title'       => 'Hero Section GOAI',
'description' => 'Secțiune hero cu titlu, subtitlu și CTA.',
'categories'  => array( 'goai-patterns' ),
'content'     => '
<!-- wp:cover {"overlayColor":"dark"} -->
<div class="wp-block-cover">
<!-- wp:heading {"textAlign":"center","level":1} -->
<h1 class="has-text-align-center">Titlu principal</h1>
<!-- /wp:heading -->
<!-- wp:paragraph {"align":"center"} -->
<p class="has-text-align-center">Subtitlu descriptiv</p>
<!-- /wp:paragraph -->
<!-- wp:buttons {"layout":{"type":"flex","justifyContent":"center"}} -->
<div class="wp-block-buttons">
<!-- wp:button -->
<div class="wp-block-button"><a class="wp-block-button__link">Află mai mult</a></div>
<!-- /wp:button -->
</div>
<!-- /wp:buttons -->
</div>
<!-- /wp:cover -->
',
)
);
}
add_action( 'init', 'goai_register_patterns' );
13

WordPress Multisite

Ce este Multisite?

WordPress Multisite permite rularea mai multor site-uri WordPress dintr-o singură instalare, cu o singură bază de date și un singur set de fișiere core. Ideal pentru rețele de site-uri, universități, corporații sau agenții.

Activare Multisite


// 1. Adăugați în wp-config.php (înainte de "That's all, stop editing!")
define( 'WP_ALLOW_MULTISITE', true );

// 2. Accesați Tools → Network Setup în admin
// 3. Alegeți: Subdomenii (site1.domeniu.ro) sau Subdirectoare (domeniu.ro/site1)
// 4. WordPress generează cod de adăugat în wp-config.php și .htaccess

Cod generat wp-config.php:


define( 'MULTISITE', true );
define( 'SUBDOMAIN_INSTALL', false ); // true pentru subdomenii
define( 'DOMAIN_CURRENT_SITE', 'domeniu.ro' );
define( 'PATH_CURRENT_SITE', '/' );
define( 'SITE_ID_CURRENT_SITE', 1 );
define( 'BLOG_ID_CURRENT_SITE', 1 );

Administrare Multisite

RolAccesPoate face
Super AdminNetwork AdminTotul: creare site-uri, instalare pluginuri/teme, gestionare utilizatori la nivel de rețea
Admin (per site)Site AdminGestionare conținut, utilizatori și setări pe site-ul propriu

Cazuri de utilizare ideale:

  • Universități - un site per facultate/departament
  • Corporații - un site per departament sau țară
  • Agenții - un site per client (cu restricții per site)
  • Rețele de bloguri - wordpress.com style
  • Multilingv - un site per limbă (alternativă la WPML)
⚠️ Când NU folosiți Multisite

Nu folosiți Multisite dacă site-urile nu au nimic în comun, dacă necesită pluginuri diferite per site, sau dacă aveți mai puțin de 3 site-uri. Multisite adaugă complexitate semnificativă. Pentru 1-2 site-uri, instalări separate sunt mai simple.

14

Migrare și deployment

Metode de migrare WordPress

MetodăComplexitateCel mai bun pentru
Plugin (All-in-One WP Migration)UșoarăSite-uri mici-medii (<500 MB)
Plugin (Duplicator Pro)Ușoară-medieSite-uri de orice dimensiune
Manual (fișiere + DB)MedieControl complet, site-uri mari
WP-CLIMedieAutomatizare, scripturi
Git + CI/CDAvansatăEchipe, deployment profesional

Migrare manuală pas cu pas

  1. Export bază de date de pe serverul vechi:
    mysqldump -u user -p database_name > backup.sql
  2. Copiere fișiere - tot directorul WordPress (sau doar wp-content/ dacă instalați WordPress proaspăt pe noul server).
  3. Creare bază de date nouă pe noul server (cPanel → MySQL Databases).
  4. Import bază de date:
    mysql -u user_nou -p database_noua < backup.sql
  5. Actualizare wp-config.php cu noile credențiale DB.
  6. Search & Replace URL-uri (cel mai important pas!):
    wp search-replace 'https://site-vechi.ro' 'https://site-nou.ro' --all-tables --precise
  7. Regenerare permalinks: Settings → Permalinks → Save Changes.
  8. Testare completă - verificați toate paginile, formularele, imaginile.

Mediu de staging

Un mediu de staging este o copie a site-ului de producție unde testați modificări înainte de a le aplica live.

Creare staging:

  • WP Toolkit (cPanel) - creare staging cu 1 click
  • WP Staging plugin - clonare site pe subdirector sau subdomeniu
  • Manual - copie fișiere + DB pe staging.domeniu.ro
💡 Workflow profesional

3 medii: Local (dezvoltare) → Staging (testare + aprobare client) → Producție (live). Niciodată nu modificați direct pe producție. Testați totul pe staging înainte.

Git Workflow pentru WordPress


# .gitignore pentru WordPress
wp-admin/
wp-includes/
wp-content/uploads/
wp-content/cache/
wp-content/upgrade/
wp-config.php
.htaccess
*.log
*.sql
node_modules/

# CE se pune în Git:
# - Tema custom (wp-content/themes/tema-mea/)
# - Plugin custom (wp-content/plugins/plugin-meu/)
# - mu-plugins/
# - composer.json (pentru dependențe PHP)
# - package.json (pentru dependențe JS/build)
15

WordPress Headless și Decoupled

Ce este Headless WordPress?

Headless WordPress folosește WordPress doar ca backend (CMS) pentru gestionarea conținutului, iar frontend-ul este construit separat cu un framework JavaScript modern (Next.js, Nuxt, Astro).

Avantaje:

  • Performanță - frontend-ul static/SSR este mult mai rapid
  • Securitate - WordPress nu este expus publicului
  • Flexibilitate - frontend-ul poate fi orice (web, mobile, IoT)
  • Scalabilitate - frontend pe CDN global (Vercel, Netlify)
  • Experiență dezvoltator - React/Vue/Svelte modern

Dezavantaje:

  • Complexitate - două sisteme de menținut
  • Preview - preview-ul din admin nu funcționează nativ
  • Plugin-uri - multe pluginuri WordPress nu funcționează (depind de frontend-ul WP)
  • Cost - hosting separat pentru frontend

Headless cu Next.js


// next.js - pages/index.js
// Fetch articole din WordPress REST API

export async function getStaticProps() {
const res = await fetch(
'https://backend-wp.goai.ro/wp-json/wp/v2/posts?per_page=10&_embed'
);
const posts = await res.json();

return {
props: { posts },
revalidate: 60, // ISR: regenerare la fiecare 60 secunde
};
}

export default function Home({ posts }) {
return (
<main>
<h1>Blog GOAI</h1>
{posts.map(post => (
<article key={post.id}>
<h2 dangerouslySetInnerHTML={{ __html: post.title.rendered }} />
<div dangerouslySetInnerHTML={{ __html: post.excerpt.rendered }} />
</article>
))}
</main>
);
}

WPGraphQL

WPGraphQL este o alternativă la REST API care expune datele WordPress prin GraphQL - un limbaj de interogare mai flexibil și eficient.


# Query GraphQL - obțineți exact datele de care aveți nevoie
query GetPosts {
posts(first: 10) {
nodes {
id
title
excerpt
date
featuredImage {
node {
sourceUrl
altText
}
}
categories {
nodes {
name
slug
}
}
}
}
}

📌 Când să alegeți Headless?

DA: proiecte mari, echipe cu experiență JavaScript, nevoi de performanță extremă, aplicații multi-platform.

NU: site-uri simple, clienți care editează frecvent, buget limitat, echipă mică fără experiență React/Next.js.

16

Automatizare cu WP-CLI

Comenzi WP-CLI avansate

WP-CLI este instrumentul de linie de comandă care permite administrarea completă a WordPress fără interfața web.

Gestionare conținut:


# Creare articol
wp post create --post_type=post --post_title="Articol nou" --post_status=publish

# Creare pagină cu conținut
wp post create --post_type=page --post_title="Despre noi" \
--post_content="Conținutul paginii." --post_status=publish

# Generare articole de test (bulk)
wp post generate --count=50 --post_type=post

# Ștergere toate articolele draft
wp post delete $(wp post list --post_status=draft --format=ids) --force

# Ștergere toate reviziile
wp post delete $(wp post list --post_type=revision --format=ids) --force

# Update meta pe toate produsele
wp post meta update $(wp post list --post_type=product --format=ids) _sale_price 99

Gestionare utilizatori:


# Creare utilizator admin
wp user create admin admin@goai.ro --role=administrator --user_pass=Parola123!

# Resetare parolă
wp user update 1 --user_pass=ParolaNoua456!

# Lista utilizatori cu rolul author
wp user list --role=author --fields=ID,user_login,user_email

# Ștergere utilizator (reasignare conținut)
wp user delete 5 --reassign=1

Gestionare pluginuri și teme:


# Instalare + activare plugin
wp plugin install wordfence --activate

# Actualizare toate pluginurile
wp plugin update --all

# Lista pluginuri cu actualizări disponibile
wp plugin list --update=available

# Dezactivare toate pluginurile (debugging)
wp plugin deactivate --all

# Instalare temă
wp theme install flavor flavor --activate

Scripturi de întreținere:


#!/bin/bash
# Script de întreținere săptămânală WordPress
# Salvați ca: /home/user/scripts/wp-maintenance.sh

SITE="/home/user/public_html"

echo "=== Întreținere WordPress - $(date) ==="

# 1. Actualizare core
wp core update --path=$SITE
wp core update-db --path=$SITE

# 2. Actualizare pluginuri
wp plugin update --all --path=$SITE

# 3. Actualizare teme
wp theme update --all --path=$SITE

# 4. Curățare bază de date
wp transient delete --all --path=$SITE
wp post delete $(wp post list --post_type=revision --format=ids --path=$SITE) --force --path=$SITE 2>/dev/null
wp db optimize --path=$SITE

# 5. Verificare integritate
wp core verify-checksums --path=$SITE

# 6. Cache flush
wp cache flush --path=$SITE

echo "=== Întreținere completă ==="
17

Accesibilitate și internaționalizare

Accesibilitate (A11y)

Accesibilitatea web asigură că site-ul dvs. poate fi folosit de toate persoanele, inclusiv cele cu dizabilități. Standardul de referință este WCAG 2.1 (Web Content Accessibility Guidelines).

Principii POUR:

  • Perceivable - conținutul trebuie să poată fi perceput (text alternativ, contrast)
  • Operable - interfața trebuie să fie operabilă (navigare cu tastatura, timp suficient)
  • Understandable - conținutul trebuie să fie inteligibil (limbaj clar, previzibil)
  • Robust - conținutul trebuie interpretat de diverse tehnologii asistive

Checklist accesibilitate WordPress:

  • Toate imaginile au atribut alt descriptiv
  • Contrast text/fundal minim 4.5:1 (AA) sau 7:1 (AAA)
  • Navigare completă cu tastatura (focus vizibil)
  • Formulare cu label-uri asociate corect
  • Ierarhie heading-uri corectă (h1 → h2 → h3, fără salturi)
  • Link-uri descriptive (nu „click aici")
  • Skip navigation link (Skip to content)
  • Atribute ARIA unde este necesar

Internaționalizare (i18n) și Localizare (l10n)

Internaționalizarea pregătește codul pentru traducere, iar localizarea realizează traducerea efectivă.

Funcții de traducere WordPress:


// Text simplu
__( 'Textul de tradus', 'text-domain' );

// Text cu echo
_e( 'Textul afișat', 'text-domain' );

// Text cu placeholder
printf(
__( 'Bun venit, %s! Aveți %d mesaje.', 'goai-plugin' ),
$username,
$count
);

// Singular/Plural
printf(
_n( '%d articol publicat', '%d articole publicate', $count, 'goai-plugin' ),
$count
);

// Text cu context (cuvinte cu sensuri multiple)
_x( 'Post', 'verb - a posta', 'goai-plugin' );
_x( 'Post', 'noun - articol', 'goai-plugin' );

// Escapare + traducere
esc_html__( 'Text HTML safe', 'goai-plugin' );
esc_attr__( 'Atribut safe', 'goai-plugin' );

// Încărcare fișiere traducere
function goai_load_textdomain() {
load_plugin_textdomain(
'goai-plugin',
false,
dirname( plugin_basename( __FILE__ ) ) . '/languages'
);
}
add_action( 'plugins_loaded', 'goai_load_textdomain' );

Pluginuri de traducere:

PluginFuncțiePreț
WPMLTraducere completă site (standard industrial)De la €39/an
PolylangTraducere site (alternativă gratuită)Gratuit / Pro
TranslatePressTraducere vizuală (frontend)Gratuit / Pro
Loco TranslateTraducere teme/pluginuri din adminGratuit
18

Debugging și troubleshooting

Debug Mode WordPress


// wp-config.php - configurare debug completă
define( 'WP_DEBUG', true );          // Activare debug
define( 'WP_DEBUG_LOG', true );       // Salvare în wp-content/debug.log
define( 'WP_DEBUG_DISPLAY', false );  // NU afișa pe ecran
define( 'SCRIPT_DEBUG', true );       // Folosire fișiere CSS/JS necompresate
define( 'SAVEQUERIES', true );        // Salvare query-uri pentru analiză
@ini_set( 'display_errors', 0 );     // Backup - ascunde erori PHP

Query Monitor (plugin)

Query Monitor este cel mai puternic plugin de debugging pentru WordPress. Afișează informații detaliate în toolbar-ul admin:

  • Database Queries - toate query-urile SQL, durata, originea
  • PHP Errors - erori, warnings, notices
  • Hooks & Actions - ce hooks s-au executat
  • HTTP Requests - cereri HTTP externe (API-uri)
  • Transients - transient-uri setate/obținute
  • Templates - ce template-uri au fost încărcate
  • Enqueued Scripts/Styles - toate CSS/JS încărcate
  • REST API - cereri REST API
  • Environment - PHP, MySQL, versiuni

Depanare erori comune

White Screen of Death (WSOD):

  1. Activați WP_DEBUG și verificați wp-content/debug.log
  2. Dezactivați toate pluginurile prin FTP (redenumiți plugins/ în plugins_off/)
  3. Activați pe rând fiecare plugin pentru a identifica vinovatul
  4. Schimbați tema la una default (Twenty Twenty-Five)
  5. Verificați limitele PHP (memory_limit, max_execution_time)

Eroare la conectare la baza de date:

  1. Verificați credențialele în wp-config.php
  2. Verificați dacă MySQL/MariaDB rulează (service status)
  3. Testați conexiunea: wp db check
  4. Verificați dacă utilizatorul DB are privilegii pe baza de date

Probleme de permisiuni:


# Corectare permisiuni WordPress
find /home/user/public_html -type d -exec chmod 755 {} \;
find /home/user/public_html -type f -exec chmod 644 {} \;
chmod 600 /home/user/public_html/wp-config.php

Debugging custom:


// Funcție de log custom
function goai_log( $message, $data = null ) {
if ( ! WP_DEBUG ) return;

$log_entry = '[' . date( 'Y-m-d H:i:s' ) . '] ' . $message;
if ( $data !== null ) {
$log_entry .= ' | Data: ' . print_r( $data, true );
}
error_log( $log_entry );
}

// Utilizare
goai_log( 'Procesare comandă', array( 'order_id' => 123, 'total' => 450 ) );
19

Integrare AI în WordPress

Utilizări AI în WordPress

Inteligența artificială poate fi integrată în WordPress pentru a automatiza și îmbunătăți diverse funcționalități:

  • Generare conținut - articole, descrieri produse, meta descriptions
  • Chatboți - asistență clienți automatizată pe site
  • Traducere automată - traducere conținut în mai multe limbi
  • SEO - sugestii optimizare, analiză conținut
  • Imagini - generare imagini, alt text automat
  • Personalizare - recomandări conținut bazate pe comportament
  • Moderare - filtrare comentarii spam/ofensatoare

Integrare Claude API


// Funcție de apel Claude API din WordPress
function goai_call_claude_api( $prompt, $system_prompt = '' ) {
$api_key = get_option( 'goai_anthropic_api_key' );
if ( empty( $api_key ) ) return false;

$body = array(
'model'      => 'claude-sonnet-4-20250514',
'max_tokens' => 1024,
'messages'   => array(
array( 'role' => 'user', 'content' => $prompt ),
),
);

if ( ! empty( $system_prompt ) ) {
$body['system'] = $system_prompt;
}

$response = wp_remote_post( 'https://api.anthropic.com/v1/messages', array(
'headers' => array(
'Content-Type'      => 'application/json',
'x-api-key'         => $api_key,
'anthropic-version' => '2023-06-01',
),
'body'    => wp_json_encode( $body ),
'timeout' => 30,
) );

if ( is_wp_error( $response ) ) {
goai_log( 'Eroare Claude API: ' . $response->get_error_message() );
return false;
}

$data = json_decode( wp_remote_retrieve_body( $response ), true );
return $data['content'][0]['text'] ?? false;
}

// Exemplu: Generare meta description
function goai_generate_meta_description( $post_id ) {
$post    = get_post( $post_id );
$content = wp_strip_all_tags( $post->post_content );
$content = mb_substr( $content, 0, 1000 ); // primele 1000 caractere

$prompt = "Generează o meta description SEO optimizată (maximum 155 caractere) "
. "în limba română pentru următorul articol:\n\n"
. "Titlu: {$post->post_title}\n\n"
. "Conținut: {$content}";

$description = goai_call_claude_api( $prompt,
'Ești un expert SEO. Răspunde doar cu meta description-ul, fără explicații.'
);

if ( $description ) {
update_post_meta( $post_id, '_goai_meta_description', $description );
}
}

Pluginuri AI pentru WordPress

PluginFuncțieAI folosit
AI EngineChatbot, generare conținut, imagini, traducereOpenAI, Claude, diverse
Jebrains AIGenerare conținut, asistent scriereMultiple
SEOPress + AIGenerare meta descriptions, titluri SEOOpenAI
Flavor (theme)Generare layout-uri și conținut din promptOpenAI
Jebrains TranslationTraducere automată conținutDeepL, Google, AI
💡 Abordare recomandată

AI-ul în WordPress funcționează cel mai bine ca asistent, nu ca înlocuitor. Folosiți-l pentru drafturi inițiale, sugestii și automatizări repetitive, dar revizuiți întotdeauna conținutul generat înainte de publicare.

20

Checklist-uri și bune practici

Checklist: Pre-lansare site WordPress

CategorieVerificare
ConținutToate paginile au conținut final (nu Lorem Ipsum)
ConținutImagini optimizate (WebP, dimensiuni corecte, alt text)
ConținutLink-uri funcționale (fără broken links)
SEOPlugin SEO activ (Yoast/Rank Math/SEOPress)
SEOTitle tags și meta descriptions pe toate paginile
SEOSitemap XML generat și trimis la Google Search Console
SEORobots.txt configurat corect
SEOSchema markup (structured data) implementat
SecuritateSSL activ, HTTPS forțat pe tot site-ul
Securitatewp-config.php hardened (DISALLOW_FILE_EDIT, etc.)
SecuritatePlugin securitate activ (Wordfence/Sucuri)
SecuritateBackup automat configurat
PerformanțăPlugin de cache activ și configurat
PerformanțăCore Web Vitals în verde (pagespeed.web.dev)
PerformanțăImagini lazy loading activat
TehnicPHP 8.2+ setat
TehnicWordPress, teme și pluginuri actualizate
TehnicFormularele funcționează (testați trimitere)
TehnicGoogle Analytics/GA4 instalat
Tehnic404 page personalizată
LegalPolitica de confidențialitate și GDPR
LegalCookie consent banner
ResponsiveTestat pe mobil, tabletă și desktop
ResponsiveFavicon și web app manifest

Checklist: Întreținere lunară WordPress

TaskTimp estimat
Actualizare WordPress core5 min
Actualizare pluginuri (pe staging mai întâi!)15 min
Actualizare teme5 min
Verificare backup-uri funcționale10 min
Curățare bază de date (revizii, transients, spam)5 min
Verificare securitate (scanare malware)10 min
Verificare broken links10 min
Testare Core Web Vitals10 min
Verificare Google Search Console (erori, indexare)15 min
Ștergere pluginuri/teme nefolosite5 min

Bune practici dezvoltare WordPress

  1. Nu modificați core-ul - folosiți hooks, child themes, pluginuri
  2. Prefixați totul - funcții, clase, hooks, opțiuni
  3. Sanitizați input, escapați output - întotdeauna
  4. Folosiți nonces - pentru toate formularele și acțiunile
  5. Folosiți $wpdb->prepare() - pentru toate query-urile directe
  6. Enqueue CSS/JS corect - wp_enqueue_scripts, nu echo direct
  7. Testați pe staging - niciodată direct pe producție
  8. Păstrați totul actualizat - core, teme, pluginuri
  9. Backup zilnic - automat, off-site
  10. Folosiți child theme - pentru personalizări teme terțe

🎓 Felicitări!

Ați parcurs cursul complet WordPress Avansat 2026 de la GOAI!

Acum aveți cunoștințele necesare pentru dezvoltare profesională WordPress: teme și pluginuri custom, REST API, securitate avansată, performanță, WooCommerce, Gutenberg blocks și integrare AI.

Succes în dezvoltarea WordPress!

© 2026 GOAI - Dorel Tănase | goai.ro

Continuați cu restul cursului

Acesta este capitolul 1 din cele 20 ale cursului, cu 4 lecții din 64. Cumpărați cursul și parcurgeți tot conținutul în cont, cu progres salvat, test final și certificat.

Cumpărați cursul la 110 €