Template ondersteuning toevoegen voor berichten in WordPress

Vraag:

Voor vrijwel alle blogs die ik schrijf gebruik ik templates die bestaan uit een aantal koppen en instellingen zoals een categorie. Iedere keer als ik een nieuw blog begin open ik de template en kopieer ik de inhoud en zet ik de instellingen over.

Maar de afgelopen tijd begon ik mijzelf af te vragen of dat niet gemakkelijker zou kunnen.

De voorkeur zou uitgaan naar een optie dat ik vanuit het nieuwe blog direct het template in kan laden. Dit inclusief de overige instellingen zoals categorie en of er wel of geen advertenties  getoond mogen worden.

In eerste instantie zat ik te denken aan de Yoast Duplicate Post plugin. Maar die doet letterlijk wat het zegt een ander bericht dupliceren. Dit sluit niet precies aan bij mijn werkwijze omdat ik vaak via de Jetpack app op mijn smartphone al concepten aanmaak met een titel + content of wat aantekeningen.

Ik was dus opzoek naar een optie om een template in een ander bericht in te laden inclusief het behoud van de reeds ingevoerde content.

Antwoord:

Ik ben zelf PHP developer van beroep dus heb ik maar besloten om zelf een maatwerk oplossing te ontwikkelen. Hoe ik dat heb gedaan kan je verder lezen in dit blog.

Stap 1:

Belangrijk om te weten is dat ik een aantal berichten in mijn WordPress website heb toegevoegd die ik gebruik als template of sjabloon. De titels van deze berichten beginnen allemaal met de “Concept”.

De berichten staan in concept, maar heb ik voor de zekerheid een publicatie datum in het jaar 9999 gegeven. Mocht ik ze per ongeluk publiceren dan worden ze nooit zichtbaar.

In een latere stap in dit blog ga ik deze berichten tonen in een selectlijst in een widget. Deze widget plaats ik in de sidebar van scherm waarin je de berichten beheert.

Stap 2:

Vervolgens heb ik de onderstaande code toegevoegd aan het functions.php bestand van mijn child theme.

Pas nooit het parent thema aan tenzij het een maatwerk thema is. Anders verlies je de wijzigingen als je een update van het thema installeert.

function child_admin_post_metabox_template() {
    $idPost = isset($_GET['post']) ? (int) $_GET['post'] : 0;
    if ($idPost > 0) {
        add_meta_box('child_admin_post_metabox_template', 'Selecteer template', 'child_admin_post_metabox_template_html', 'post', 'side');
    }
}
add_action( 'add_meta_boxes', 'child_admin_post_metabox_template');

Met bovenstaande code voeg ik een metabox toe aan het scherm “post” (berichten scherm) in de “side” zijbalk. Voor meer informatie zie de documentatie van add_meta_box().

Stap 3:

Om de metabox zichtbaar te maken op het scherm heb ik gebruik gemaakt van onderstaande code. De functie child_admin_post_metabox_template_html() zie je ook terugkomen in de code van stap 2.

function child_admin_post_metabox_template_html($post) {
    global $wpdb;

    echo '<select name="child_admin_post_metabox_template_select" id="child_admin_post_metabox_template_select" class="postbox">' . PHP_EOL;
    echo '<option value="">Kies een template...</option>' . PHP_EOL;

    $myposts = $wpdb->get_results("SELECT id, post_title FROM $wpdb-&gt;posts WHERE post_status='draft' AND post_title LIKE 'Concept %'");
    foreach($myposts as $mypost) {
        $data = get_post($mypost);
        $url  = get_site_url() . '/wp-admin/post.php?post=' . (int)$_GET['post'] . '&amp;action=edit&amp;template=' . (int) $data->id;
        echo '<option value="' . esc_attr($url) . '">' . esc_html($data-&gt;post_title) . '</option>' . PHP_EOL;
    }

    echo '</select>' . PHP_EOL;
    echo '<input type="button" class="button" value="Toevoegen" id="child_admin_post_metabox_template_button">';
}

Deze code vult de metabox met de HTML opmaak om een formulier te tonen met:

  • Een selectlijst > gevuld met de templates uit stap 1 die ik inlaad via een SQL query
  • Een button > om de gekozen template naar de server te sturen
Template ondersteuning in metabox widget in Berichten scherm.
Zo komt het er dan uit te zien.

Stap 4:

Om het formulier daadwerkelijk te versturen, ook wel submitten, maak ik gebruik van onderstaande Javascript code die ik met PHP toevoeg.

 

Bovenstaande code is een afbeelding omdat je niet direct Javascript kan toevoegen aan een bericht in WordPress. Dit wordt dan uitgevoerd door de browser waardoor het onleesbaar wordt.

Het Javascript wordt ingeladen ingeladen via de functie admin_print_footer_scripts-post.php():

  • admin > geeft aan dat je ingelogd moet zijn in de wp-admin omgeving
  • post-php > geeft aan dat de code alleen voor de berichten pagina ingeladen moet worden
  • print_footer > zorgt ervoor dat het script in de footer aan het einde wordt ingeladen

Stap 5:

De laatste stap is de code die het verstuurde formulier verwerkt, dus die mijn bericht samenvoegt met het gekozen template. De titel en content blijft behouden.

Hiervoor heb ik de functie child_admin_process_chosen_template() toegevoegd.

function child_admin_process_chosen_template() {
    $templatePost = null;
    $currentPost  = null;

    // Check if the needed post ids are available in the URL.
    if (isset($_GET['template']) && is_numeric($_GET['template'])) {
        $idTemplate     = (int) $_GET['template'];
        $templatePost   = get_post($idTemplate, ARRAY_A);
    }
    if (isset($_GET['post']) && is_numeric($_GET['post'])) {
        $idPost         = (int) $_GET['post'];
        $currentPost    = get_post($idPost, ARRAY_A);
    }

    // Check if the post settings are found and if so combine both and update the current post.
    if (null !== $templatePost && null !== $currentPost) {
        $postTitle      = $currentPost['post_title'];
        $postContent    = $currentPost['post_content'];

        // Merge the template content with the content of the current post.
        if (0 !== strlen($postContent)) {
            $postContent = $templatePost['post_content'] . '<br />---- Originele content ----<br />' . $postContent;
        } else {
            $postContent = $templatePost['post_content'];
        }

        // Use the template as example but overrule some fields with their original values.
        $currentPost                    = $templatePost;
        $currentPost['ID']              = $idPost;
        $currentPost['post_title']      = $postTitle;
        $currentPost['post_content']    = $postContent;

        wp_update_post($currentPost);

        // Get the categories from the template and add it to this post.
        $categories = get_the_category($idTemplate);
        foreach ($categories as $category) {
            wp_set_post_categories($idPost, array($category->term_id), true);
        }

        // Get the post meta settings from the template and add it to the current post.
        $postMetaItems = ['add_your_meta_keys_here'];
        foreach ($postMetaItems as $postMetaItem) {
            $value = get_post_meta($idTemplate, $postMetaItem, true);
            update_post_meta($idPost, $postMetaItem, $value);
        }

        // Redirect the user to prevent that the actions are done again when reloading the page.
        wp_safe_redirect(get_site_url() . '/wp-admin/post.php?post=' . $idPost . '&action=edit');
    }
}
add_action( 'admin_init', 'child_admin_process_chosen_template', 1);

Deze wordt iedere keer dat een pagina in wp-admin ingeladen wordt uitgevoerd. Maar als er geen template en post waarde in de URL zit of of de waardes zijn ongeldig, dan wordt de code niet verder uitgevoerd.

Ik denk dat de documentatie in de functie genoeg uitleg geeft. Het resultaat is dat het huidige bericht aangevuld wordt met content en instellingen van de gekozen template.

> Bekijk andere blogs over WordPress

Getest op:

WordPress 6.5.2

Laat een reactie achter

Your email address will not be published. Required fields are marked *

Deze site gebruikt Akismet om spam te verminderen. Bekijk hoe je reactie-gegevens worden verwerkt.