POC: CMS

Workshop : Proof of Concept

Aanleiding

De back-end van het Koffiekaartje moet goed ingedeeld worden. Het moet namelijk ook makkelijk inzetbaar zijn voor toekomstige Horekaartje concepten. Met een aantal simpele handelingen moet het thema namelijk operatief kunnen zijn in een nieuwe WordPress omgeving.  Uit het CMS onderzoek is gebleken dat een website goed te  hergebruiken valt doormiddel van een maatwerk gebouwd thema. Via een maatwerk thema kan je de website namelijk helemaal bouwen naar jouw eigen specificaties via HTML/CSS en PHP. Zonder dat je allemaal onnodige plug-ins en toevoegingen moet gebruiken die de laadsnelheid en de performance van de website érg vertragen.

Deze POC bestaat daarom ook uit vier onderdelen die de volledige basis vormt om verder te kunnen uitbouwen naar een compleet dynamisch Koffiekaartje.

  • Custom WordPress thema
  • Inbouwen van ACF
  • Inbouwen van een ACF-site opties pagina
  • Custom Post Type

https://github.com/Casie150/horecaartje

 

Onderzoeksvraag:
Hoe bouw je een CMS goed op voor het Koffiekaartje?

Doelen

  • Future-proof develop omgeving ontwikkelen
  • Gemakkelijke overdracht waarborgen
  • GIT omgeving opzetten
  • CPT opbouwen

Resultaten

Custom WordPress thema

Om complete vrijheid te hebben met het opbouwen van mijn code wou ik niet gebonden zitten aan een standaard WordPress thema. Ik heb daarom mijn  eigen thema opgebouwd vanuit een kale WordPress thema omgeving. Ik heb als basis hiervoor HTMl5 Blank gebruikt. Binnen deze omgeving heb ik ACF ingebouwd, een overzichtelijke structuur opgebouwd voor mijn PHP, SCSS, CSS, pagina-templates, functies en foto’s. En is later nog Woocommerce ingebouwd en toegevoegd aan de functions. Hierdoor heb ik complete development vrijheid voor mezelf kunnen creëren.

 

Inbouwen van ACF

ACF is ingebouwd als plug-in, ook heb ACF toegang moeten geven aan de Google Maps API zodat ik locaties kan toevoegen aan mijn horecazaken later in het proces.

function my_acf_init() {
   
    acf_update_setting('google_api_key', 'AIzaSyAvw6Sq5OEJjBaL_zS3YGzFxt10KnNeSOo');
}


add_action('acf/init', 'my_acf_init');

Inbouwen van een ACF-site opties pagina

Om overzichtelijk aanpassingen te doen binnen de WordPress omgeving heb ik een website instellingen pagina aangemaakt met ACF. Met het ACF-optionsveld is het mogelijk om PHP data in te laden door je gehele website en deze gemakkelijk aan  te passen via een overzichtelijk UI binnen je CMS.

if (function_exists('acf_add_options_page')) {
    acf_add_options_page(array(
    'page_title' => 'Horekaartje',
    'menu_title' => 'Horekaartje',
    'menu_slug' => 'Horekaartjes',
    'capability' => 'edit_posts',
    'icon_url' => 'dashicons-heart',
    'redirect' => false
    ));
}

Via een stukje software van ACF maak ik in de achterkant PHP arrays aan die ik kan oproepen in mijn front-end. Deze worden toegevoegd aan de opties pagina via een opties knop.

Uiteindelijk print WordPress het dan zo uit als een instellingen pagina.

Custom Post Type

De keuze om een Custom Post Type is gemaakt samen met de stakeholders en developers van Koffiekaartje. Custom Post Types geven je een hoop vrijheid om elementen toe te voegen aan een custom WordPress pagina of post. In combinatie met ACF geeft je dit veel vrijheid om de pagina’s in te delen zoals ik wil. Dit is echter een complexe uitleg die beter in een video is uit te leggen. Hieronder voeg ik de basis CPT opbouw toe. En in de conclusie ga ik daarom dieper in op de algemene opbouw en de keuze voor een CPT.

<?php
/*
 * Custom post type "Horecazaken" aanmaken
 */
function create_horecazaak_cpt()
{
    $labels = array(
        'name'                  => _x('horecazaak', 'Post Type General Name'),
        'singular_name'         => _x('horecazaak', 'Post Type Singular Name'),
        'menu_name'             => _x('Horecazaken', 'Admin Menu text'),
        'name_admin_bar'        => _x('Horecazaken', 'Add New on Toolbar'),
        'archives'              => __('Horecazaken'),
        'attributes'            => __('Horecazaak attributen'),
        'parent_item_colon'     => __('Parent horecazaken'),
        'all_items'             => __('Alle horecazaken'),
        'add_new_item'          => __('Horecazaak toevoegen'),
        'add_new'               => __('Nieuwe horecazaak'),
        'new_item'              => __('Horecazaak toevoegen'),
        'edit_item'             => __('Horecazaak bewerken'),
        'update_item'           => __('Horecazaak updaten'),
        'view_item'             => __('Horecazaak bekijken'),
        'view_items'            => __('Horecazaak bekijken'),
        'search_items'          => __('Horecazaak zoeken'),
        'not_found'             => __('Geen Horecazaken gevonden.'),
        'not_found_in_trash'    => __('Geen Horecazaken gevonden in de prullenbak.'),
        'featured_image'        => __('Uitgelichte afbeelding'),
        'set_featured_image'    => __('Uitgelichte afbeelding instellen'),
        'remove_featured_image' => __('Uitgelichte afbeelding verwijderen'),
        'use_featured_image'    => __('Uitgelichte afbeelding instellen'),
        'insert_into_item'      => __('Invoegen in horecazaak'),
        'uploaded_to_this_item' => __('Geüpload naar dit product'),
        'items_list'            => __('Productenlijst'),
        'items_list_navigation' => __('Productenlijst navigatie'),
        'filter_items_list'     => __('Filter productenlijst'),
        'rewrite'           => array(
            'slug' => 'horecazaken',
            'with_front' => false
        ),
    );
    $horecazaak = array(
        'label'                 => __('Horecazaken'),
        'description'           => __('Horecazaken van Horecaartje'),
        'menu_icon'             => 'dashicons-food',
        'supports'              => array('title', 'custom-fields', 'thumbnail'),
        'public'                => true,
        'slug'                  => 'horecazaken',
        'show_ui'               => true,
        'show_in_menu'          => true,
        'menu_position'         => 2,
        'show_in_admin_bar'     => true,
        'show_in_nav_menus'     => true,
        'can_export'            => true,
        'has_archive'           => true,
        'hierarchical'          => false,
        'exclude_from_search'   => false,
        'show_in_rest'          => true,
        'query_var'             => 'horecazaken',
        'publicly_queryable'    => true,
        'capability_type'       => 'post',
        'rewrite'           => array(
            'slug' => 'horecazaken',
            'with_front' => false
        ),
    );
    register_post_type('horecazaak', $horecazaak);
}
add_action('init', 'create_horecazaak_cpt', 0);


function create_categorie()
{
    $labels = array(
        'name'                  => _x('Categorieën', 'taxonomy general name'),
        'singular_name'         => _x('Categorie', 'taxonomy singular name'),
        'search_items'          => __('Categorieën zoeken'),
        'all_items'             => __('Alle categorieën'),
        'parent_item'           => __('Parent categorie'),
        'parent_item_colon'     => __('Parent categorie:'),
        'edit_item'             => __('Categorie bewerken'),
        'update_item'           => __('Categorie updaten'),
        'add_new_item'          => __('Categorie toevoegen'),
        'new_item_name'         => __('Nieuwe categorienaam'),
        'menu_name'             => __('Categorieën'),
    );
    $horecazaak = array(
        'labels'                => $labels,
        'description'           => __('De categorieën van de deelneemende horecazaken'),
        'hierarchical'          => true,
        'public'                => true,
        'publicly_queryable'    => true,
        'show_ui'               => true,
        'show_in_menu'          => true,
        'show_in_nav_menus'     => true,
        'show_tagcloud'         => true,
        'show_in_quick_edit'    => true,
        'show_admin_column'     => true,
        'show_in_rest'          => true,
        'query_var'             => true,
        'rewrite'               => array('slug' => 'categorie'),
    );
    register_taxonomy('categorie', array('horecazaak'), $horecazaak);
}
add_action('init', 'create_categorie');

Aanmaken van losse pagina’s en post per horecazaak en het toevoegen van de unieke eigenschappen categorieën.  

Via een array loop kan ik nu gemakkelijk Horecazaken oproepen vanuit de back-end. Via een include roep ik alsvolgt alle losse post types op in een repeat.

<?php $results_args = array(
                            'post_type' => 'horecazaak',
                            'post_status' => 'publish',
                            'orderby' => 'date'
                        ); ?>
                    <?php endif; ?>


                    <?php $results_query = new WP_Query($results_args); ?>
                   
                        <?php if ($results_query->have_posts()) : ?>
                           
                            <?php while ($results_query->have_posts()) : $results_query->the_post(); ?>
                           
                                <?php if($results && $proximity) :?>
                                    <?php $address = get_field('horecazaak_location'); ?>
                                    <?php $distance = horecaartje_get_distance($origin, $address['lat'], $address['lng'], $unit); ?>
                                   
                                <?php endif; ?>                            
                                <?php include 'inc/horecaak_archive_post.php'; ?>
                            <?php endwhile; ?>
                        <?php else : ?>
                            Geen horecazaken gevonden
                        <?php endif; ?>

De losse data uit de post wordt opgehaald via een include. Dit haalt hij op het een WordPress archive sectie.

<?php
$parent_terms_horecazaak = get_the_terms( $post->ID, 'categorie' );
$cart_ids = [];
foreach ( WC()->cart->get_cart() as $cart_item_key => $cart_item ) {
  $product = $cart_item['data'];
  $cart_ids[] = $product->get_id();
}
?>
<a class="horecazaak" href="<?php the_permalink(); ?>" title="<?php the_title(); ?>" data-category="<?php if( $parent_terms_horecazaak ) : ?><?php foreach ( $parent_terms_horecazaak as $pterm_horecazaak ) : ?><?php echo strtolower($pterm_horecazaak->name); ?> <?php endforeach; ?><?php endif; ?>">
    <article>
        <div class="horecazaak_wrap">
           
            <?php if (in_array($post->ID, $cart_ids)): ?>
                <div class="horecazaak_add_to_cart horecazaak_added">
                    <span value="<?php echo $post->ID ?>" class="<?php echo($status_add_cart); ?>  add_to_cart_button single_add_to_cart_button in_cart">
                        <i class="material-icons-outlined">check</i>
                    </span>
                </div>
            <?php else: ?>
                <div class="horecazaak_add_to_cart">
                    <button type="submit" name="add-to-cart" value="<?php echo $post->ID ?>" class="<?php echo($status_add_cart); ?> ajax_add_to_cart add_to_cart_button single_add_to_cart_button" data-product_id="<?php echo $post->ID ?>" aria-label="Add <?php the_title_attribute() ?> to your cart">
                        <i class="material-icons-outlined">add</i>
                    </button>
                </div>
            <?php endif; ?>


            <?php $horecazaak_img = get_field('horecazaak_img'); ?>
            <?php if( !empty( $horecazaak_img ) ): ?>
                <img class="horecazaak_img" alt="<?php echo esc_url($horecazaak_img['alt']); ?>" src="<?php echo esc_url($horecazaak_img['sizes']['large']); ?>" />
            <?php endif; ?>
        </div>
        <div class="horecazaak_text">
            <h2 class="horecazaak_name"><?php echo the_title(); ?></h2>
            <div class="horecazaak_categories">
                <ul>
                    <?php if( $parent_terms_horecazaak ) : ?>
                        <?php foreach ( $parent_terms_horecazaak as $pterm_horecazaak ) : ?>
                            <li>
                                <?php echo $pterm_horecazaak->name; ?></span>
                            </li>
                        <?php endforeach; ?>
                    <?php endif; ?>
                </ul>
            </div>
            <?php if($results && $proximity) : ?>
                <div class="horecazaak_distance"><i class="material-icons">location_on</i><span><?php  echo $origin ?  round($distance, 1) . " " . "Km"  : '' ;?></span></div>
            <?php endif; ?>
        </div>
    </article>
</a>