WordPress

Ai deja un site WordPress? Îndreaptă-ți blogul spre el și fiecare articol pe care îl publici aici e trimis acolo automat — ca un articol WordPress real, în tema ta, la permalinkurile tale. Fără plugin de instalat. WordPress core are tot ce e nevoie încă din versiunea 5.6: API-ul REST și parolele de aplicație.

Conectare în trei pași

  1. Creează o parolă de aplicație în WordPress

    În WordPress, mergi la Utilizatori → Profil, derulează la Parole de aplicație, scrie un nume (baas) și apasă Adaugă o parolă de aplicație nouă. WordPress arată o parolă de 24 de caractere o singură dată — copiaz-o acum.

    Conectează-te ca administrator sau editor. Aceste roluri dețin capacitatea unfiltered_html, care e ceea ce permite conținutului tău bogat să ajungă intact — vezi Ce supraviețuiește trimiterii mai jos.

  2. Lipește-o în cardul de livrare al blogului

    Pe pagina blogului tău din baas, găsește Unde ajung articolele, comută livrarea pe Trimite în WordPress și completează:

    Câmp Valoare
    URL-ul site-ului WordPress Rădăcina site-ului tău, ex. https://example.com — nu URL-ul /wp-admin
    Utilizator WordPress Numele de autentificare al acelui utilizator, nu emailul lui
    Parolă de aplicație Șirul de 24 de caractere, cu tot cu spații
    Articolele ajung ca Publicate, sau Ciornă dacă vrei o privire finală în interiorul WordPress

    Stocăm parola criptată (AES-256-GCM) și n-o mai afișăm niciodată — câmpul rămâne gol la fiecare vizită ulterioară, iar salvarea cu el gol păstrează parola stocată.

  3. Testează conexiunea

    Apasă Testează conexiunea. Un rezultat verde numește utilizatorul WordPress cu care ne-am autentificat. Orice altceva îți spune exact ce a zis WordPress — vezi Depanare mai jos.

Ce se trimite, și când

Un articol e trimis când devine publicat — în momentul în care îl aprobi în coada de revizuire, sau în momentul în care auto-publicarea îl publică pentru tine. Trimiterea poartă:

Câmp WordPressDe unde
titleTitlul articolului
slugSlug-ul articolului — permalinkul tău rămâne predictibil
contentHTML-ul randat, împachetat și stilizat (mai jos)
excerptRezumatul generat
statusOrice ai ales la Articolele ajung ca
date_gmtOra de publicare înregistrată aici

Trimiterea din nou actualizează același articol WordPress în loc să creeze unul al doilea: reținem id-ul articolului WordPress. Dacă ștergi articolul din interiorul WordPress, următoarea trimitere îl recreează.

Retragerea unui articol

Retrage articolul îl scoate și de aici, și din WordPress: articolul nu mai este servit de noi, iar copia din WordPress revine la ciornă, deci răspunde 404 pe site-ul tău, în timp ce conținutul rămâne în CMS-ul tău. Nu ștergem niciodată un articol de pe site-ul tău și nu îl trimitem la coșul de gunoi — ciorna păstrează același id de articol WordPress, așa că Publică din nou scrie peste același articol în loc să creeze unul al doilea.

Dacă WordPress nu poate fi contactat, retragerea reîncearcă cu backoff și cardul arată eroarea; articolul e deja retras aici, oricum.

Ce supraviețuiește trimiterii

Articolele noastre sunt mai bogate decât HTML simplu — callout-uri, ghiduri pas cu pas, panouri de comparație, grafice, cod adnotat. WordPress decide cât de mult din asta acceptă în funcție de o singură capacitate a utilizatorului cu care te-ai conectat: unfiltered_html.

Cu ce utilizator te-ai conectat?
Administrator sau editor

Deține unfiltered_html pe o instalare single-site.

  • Stilizare completă a componentelor — trimitem un bloc <style> scoped
  • Grafice, diagrame de flux, sparkline-uri (SVG) — toate se randează
  • Paleta de temă a blogului tău călătorește odată cu conținutul
  • Stilurile sunt scoped la wrapper-ul nostru și nu îți pot repicta tema
Autor, colaborator, sau orice utilizator multisite

Nu deține unfiltered_html, așa că WordPress îți trece conținutul prin filtrul lui KSES.

  • Trimitem în mod deliberat niciun bloc <style> — WordPress elimină tagurile, dar lasă CSS-ul în urmă ca text vizibil, ceea ce ar arunca o foaie de stil în articolul tău
  • SVG e eliminat complet, deci graficele și diagramele dispar
  • Textul, titlurile, listele, tabelele, codul, structura de callout-uri tot ajung

Dashboard-ul te avertizează despre asta după un test de conexiune, ca să afli înainte să afle cititorii tăi. Pe WordPress multisite, doar un Super Admin deține unfiltered_html — asta e o regulă WordPress, nu a noastră.

Câmpuri SEO (Yoast și Rank Math)

Trimitem fraza cheie țintă, titlul SEO și meta descrierea, atât pentru Yoast SEO, cât și pentru Rank Math, la fiecare trimitere. Dacă rămân sau nu ține de site-ul tău:

Ca să rămână, pune acest plugin must-use în wp-content/mu-plugins/baas-seo-bridge.php — byte-identic cu fișierul pe care stack-ul compose al acestui proiect îl montează în propria țintă de dogfood WordPress:

<?php
/**
 * Plugin Name: baas SEO bridge
 * Description: Exposes the Yoast SEO and Rank Math post-meta fields over the
 *              WordPress REST API so an external publisher can set the focus
 *              keyphrase, SEO title, and meta description when it pushes a
 *              post. Without this, WordPress silently drops those keys. Also
 *              registers the _baas_post_id ownership marker so a retried push
 *              recognises a post it already created and updates it in place
 *              instead of publishing a duplicate — and never touches a post it
 *              did not create.
 * Version:     1.1.0
 * License:     MIT
 *
 * Drop this file in wp-content/mu-plugins/ — must-use plugins load
 * automatically and cannot be deactivated by accident.
 */

defined('ABSPATH') || exit;

add_action('init', function () {
    $keys = [
        // Yoast SEO. Leading underscore = protected meta, which the REST API
        // refuses to touch unless it is registered with an auth_callback.
        '_yoast_wpseo_focuskw',
        '_yoast_wpseo_metadesc',
        '_yoast_wpseo_title',
        // Rank Math. Not underscore-prefixed, but still unregistered for REST
        // on a stock install, so it needs the same treatment.
        'rank_math_focus_keyword',
        'rank_math_description',
        'rank_math_title',
        // baas ownership marker: our own post uuid, written on create and read
        // back (context=edit) so an id-less retry adopts only the post WE made.
        '_baas_post_id',
    ];

    foreach ($keys as $key) {
        register_post_meta('post', $key, [
            'type'          => 'string',
            'single'        => true,
            'show_in_rest'  => true,
            'auth_callback' => function ($allowed, $meta_key, $post_id) {
                // Same gate the editor screen uses: whoever may edit the post
                // may set its SEO fields.
                return current_user_can('edit_post', $post_id);
            },
        ]);
    }
});

// Keep the ownership marker out of PUBLIC (view-context) REST responses. We
// only ever read it back in edit context (authenticated) to recognise a post
// we created; exposing it to anonymous callers would leak our internal post
// id and baas provenance on the customer's own public site.
add_filter('rest_prepare_post', function ($response, $post, $request) {
    if (($request['context'] ?? 'view') !== 'edit') {
        $data = $response->get_data();
        if (isset($data['meta']['_baas_post_id'])) {
            unset($data['meta']['_baas_post_id']);
            $response->set_data($data);
        }
    }
    return $response;
}, 10, 3);

Tot restul — titlu, slug, conținut, rezumat, dată de publicare, status — funcționează pe WordPress standard, fără niciun plugin.

Sau trage articolele cu plugin-ul

Dacă preferi să nu ne dai o parolă de aplicație, instalează plugin-ul DailySmith Sync și lasă WordPress-ul să tragă el articolele. Interoghează fluxul de sincronizare din oră în oră cu cheia publică a site-ului tău, creează sau actualizează articolele cu același conținut, câmpuri SEO, imagine reprezentativă și stilizare pe care le trimite și push-ul, și nu suprascrie niciodată un articol pe care nu l-a creat el. Înregistrează și câmpurile SEO și marcajul de proprietate de mai sus, deci cu el instalat nu mai ai nevoie de snippet-ul bridge, iar un site care rulează ambele canale ajunge la un singur articol WordPress per articol.

Plugin-ul e open source (MIT) și stă pe GitHub: TechnicalInsideTI/dailysmith-wordpress-plugin. Descarcă arhiva zip din ultima versiune publicată, încarc-o din Module → Adaugă modul nou, apoi deschide Setări → DailySmith Sync și lipește cheia pk_….

Depanare

Ce veziCe înseamnă
401 (incorrect_password)Parola de aplicație e greșită sau a fost revocată. Generează una nouă — valoarea veche e irecuperabilă.
401 cu o parolă corectăServerul tău elimină headerul Authorization. Pe Apache, adaugă RewriteRule .* - [E=REMOTE_USER:%{HTTP:Authorization}] chiar după RewriteEngine On în .htaccess.
403 (rest_cannot_create)Utilizatorul s-a autentificat, dar nu are voie să creeze articole. Folosește un editor sau un administrator.
404 pe ruta RESTPermalinkurile prietenoase sunt oprite, sau un plugin de securitate a dezactivat API-ul REST. Setează Setări → Permalinkuri la orice altceva decât „Simplu".
„returned something that is not JSON"URL-ul nu e rădăcina site-ului — folosește https://example.com, nu https://example.com/wp-admin.
„Application passwords are not available"WordPress oferă parole de aplicație doar peste HTTPS. Pune site-ul în spatele TLS.
Stilizare lipsă pe WordPressUtilizatorul conectat nu deține unfiltered_html — vezi Ce supraviețuiește trimiterii mai sus.

Note de securitate

  • Parola de aplicație e stocată criptată la repaus (AES-256-GCM, cu un nonce proaspăt per valoare, iar textul cifrat legat de blogul căruia îi aparține). Nu e niciodată returnată de vreun răspuns API, niciodată logată și niciodată randată în dashboard.
  • O parolă de aplicație nu e autentificarea ta WordPress. Revocarea ei din Utilizatori → Profil ne taie accesul imediat și nu schimbă nimic altceva.
  • Dă-i cel mai mic rol care poate publica. Editor e de obicei potrivit; administrator e necesar doar dacă vrei și câmpuri SEO la nivel de plugin, setate de un utilizator care poate instala fragmentul-punte.
  • Cerem https:// pentru URL-ul site-ului. O parolă de aplicație trimisă peste HTTP simplu poate fi citită de orice se află pe traseu.

Notă pentru auto-găzduire

Operatorii care își rulează propria instanță baas trebuie să seteze BAAS_ENCRYPTION_KEY la 32 de octeți aleatori, codificați base64 (openssl rand -base64 32); fără ea, API-ul refuză să stocheze credențiale WordPress. Ca să rotești: mută valoarea curentă în BAAS_ENCRYPTION_KEYS_OLD (separate prin virgulă, doar pentru decriptare), pune o cheie nouă în BAAS_ENCRYPTION_KEY și repornește. Credențialele stocate continuă să funcționeze pentru că vechea cheie încă le decriptează — dar nu sunt re-criptate automat. Ca să retragi complet cheia veche, re-salvează fiecare conexiune WordPress (asta o rescrie cu cheia nouă), apoi elimină cheia retrasă din BAAS_ENCRYPTION_KEYS_OLD.

enro