Leer werken met WordPress Custom Post Types

WordPress biedt sinds versie 3 de ‘custom post types’ aan, maar wat zijn dat eigenlijk? Wat kun je ermee en vooral, hoe doe je dat? In mijn WordPress boek wordt dit onderwerp niet behandeld. Daarom deze keer een langer en meer technisch artikel, want je zult aan de bestanden van je theme gaan sleutelen.

Om duidelijk te maken waar we het hier over hebben: de normale wordpress (blog)artikelen die je schrijft zijn een ‘post type’ van het type ‘artikel’. Custom Post Types zijn daarmee dus vergelijkbaar. Maar dan niet om artikelen mee te schrijven, maar om iets anders mee te doen. Wat? Bedenk het maar! Je kunt het bijvoorbeeld inzetten om een sectie met ‘veelgestelde vragen’ (faq) te maken. Of een aparte boekensectie op je blog, een portfolio gedeelte op je website? Je kunt het zo gek niet bedenken of het valt met de Custom Post Types te maken. Soms wordt deze techniek gebruikt door theme bouwers om een WordPress theme net wat extra’s te geven. Hieronder laat ik je zien hoe je zelf gebruik kunt maken van de custom post types, onafhankelijk van het theme dat je gebruikt. Overigens, in WordPress 3.1 zijn ook de zogenaamde ‘post formats’ geïntroduceerd. En er is soms sprake van een zekere overlap tussen de post formats en de custom post types. Meer over de post formats volgt in een later artikel. Schrijf je hiernaast dus even in voor de gratis nieuwsbrief mocht je deze nog niet ontvangen!

Aan de slag!
In dit voorbeeld kies ik voor het maken van een portfolio sectie, waarmee ik mijn bezoekers kan tonen welke websites ik al voor klanten heb gerealiseerd. Om te beginnen moet je een stukje code toevoegen in de functions.php van je theme. voordat ik het vergeet: werk op een lokale kopie, ga nooit direct aanpassingen doen in je live theme, dat is vragen om problemen! Weet je niet waar de functions.php van je theme zich bevindt? Was het eerste deel van dit artikel lastig te volgen? Dan mis je een stuk WordPress basiskennis en het is in dat geval beter deze tutorial nog even links te laten liggen. Lees mijn boek Kickstart WordPress voordat je begint aan het sleutelen aan themes!

Ok, daar gaan we. Plaats de volgende code in de functions.php van je theme. Let op: doe dit bovenin het functions.php bestand!

require_once('portfolio-posttype.php');

Uiteraard deze code wel even invoegen als php code, anders gaat het niet werken.
Deze code zorgt er eigenlijk alleen maar voor dat een ander bestand, met de naam portfolio-posttype.php zal worden aangeroepen.

Vervolgens hebben we twee nieuwe bestanden nodig die je aanmaakt met je editor: de eerste is inderdaad portfolio-posttype.php en de tweede is portfolio.css, die we later zullen gebruiken om de styling te verzorgen. Begin in portfolio-posttype.php weer met de php open- en sluit-tags, anders zal onderstaande code niet als php code worden gezien. Plak deze code in het php bestand:

if ( function_exists( 'add_theme_support' ) ) {
 add_theme_support( 'post-thumbnails' );
 set_post_thumbnail_size( 400, 210, true ); // Post thumbnail afmetingen
 add_image_size( 'screen-shot', 800, 420 ); // Volledig grootte
}

Deze functie zorgt ervoor dat ik straks met de zogenaamde post thumbnails kan werken. Die functie gebruiken we om een schermafbeelding in mijn portfolio klein weer te geven, terwijl ik in werkelijkheid het bestand in een groter formaat zal plaatsen.

De inhoud van het nieuwe Post type
Goed, nu wordt het wat ingewikkelder, want nu moeten we WordPress vertellen hoe ons ‘Post type’ er precies uit komt te zien. Voeg de volgende code toe aan portfolio-posttype.php:

add_action('init', 'portfolio_register');
function portfolio_register() {
$args = array(
'label' => __('Portfolio'),
'singular_label' => __('Project'),
'public' => true,
'show_ui' => true,
'capability_type' => 'post',
'hierarchical' => false,
'rewrite' => true,
'supports' => array('title', 'editor', 'thumbnail')
);
register_post_type( 'portfolio' , $args );
}

We gebruiken voor ons nieuwe Post type dezelfde velden als bij een standaard artikel. Dat hoeft overigens niet, je kunt je Post type exact zo indelen als je zelf wilt. Het gedeelte ‘supports’=>array… zorgt ervoor dat alleen de gewenste velden te benutten zijn. Een overzicht van alle parameters die je kunt gebruiken vind je in de WordPress codex.

Taxonomy
Vervolgens voegen we een zogenaamde ‘Custom Taxonomy’ toe op deze wijze:

register_taxonomy("project-type", array("portfolio"), array("hierarchical" => true, "label" => "Project Types", "singular_label" => "Project Type", "rewrite" => true));

Dit zorgt ervoor dat mijn portfolio straks een eigen ‘categorie indeling’ kent, die we ‘Project type’ noemen. Meer informatie over de register_taxonomy functie vind je hier.

Custom field
We zijn er echter nog niet, want ik vind het belangrijk om wat extra informatie bij mijn Portfolio op te kunnen slaan. Ik gebruik hiervoor een apart, custom field. Wat ik minimaal nodig heb is de link naar het betreffende project, zodat bezoekers ook daadwerkelijk het resultaat kunnen bekijken. Dit doe je als volgt. Onderstaande code gaat wederom in de portfolio-posttype.php

add_action("admin_init", "portfolio_meta_box");

function portfolio_meta_box(){
 add_meta_box("projInfo-meta", "Project Options", "portfolio_meta_options", "portfolio", "side", "low");
}

function portfolio_meta_options(){
 global $post;
 if ( defined('DOING_AUTOSAVE') && DOING_AUTOSAVE ) return $post_id;
 $custom = get_post_custom($post->ID);
 $link = $custom["projectLink"][0];
?>
 <label>Link:</label><input name="projectLink" value="<?php echo $link; ?>" />
<?php
}

Deze code zorgt ervoor dat er een box wordt gemaakt met het nieuwe veld erin waarin ik de link kan opnemen. Echter, standaard zal WordPress deze data niet opslaan, dus daar moeten we ook zelf voor zorgen. Voeg deze code toe:

add_action('save_post', 'save_project_link');  function save_project_link(){     global $post;       if ( defined('DOING_AUTOSAVE') && DOING_AUTOSAVE ){ 		return $post_id; 	}else{     	update_post_meta($post->ID, "projectLink", $_POST["projectLink"]);
    }
}

Ok, laten we eens in de WordPress backend kijken wat we tot nu toe hebben:
Het nieuwe custom post type in de wordpress backend
Dat ziet er niet slecht uit! Aan de linkerzijde is in het menu een apart gedeelte voor het Portfolio toegevoegd en aan de rechterzijde zien we het custom field terug waarin we onze link kunnen opnemen. Ook zie je dat er een aparte categorie indeling is voor het Portfolio. Maar er moet toch nog wel wat meer gedaan worden. WordPress zal de Portfolios namelijk nog niet kunnen weergeven. Daar moeten we eerst een template voor maken. We beginnen echter met het toevoegen van een functie aan de functions.php:

function getportfolio_thumbnailurl($pid){
	$image_id = get_post_thumbnail_id($pid);
	$image_url = wp_get_attachment_image_src($image_id,'Screenshot');
	return  $image_url[0];
}

Deze functie zorgt voor het ophalen van de schermafbeelding die we bij elk Portfolio item zullen opnemen in de ‘post thumbnail’.

Nu moeten we een zogenaamd pagina template aanmaken, zodat we het Portfolio ook daadwerkelijk kunnen weergeven. Maak hiervoor een nieuw bestand aan en noem dat page-portfolio.php.

<?php
/* Template Name: Portfolio */
get_header();
query_posts('post_type=portfolio&posts_per_page=6'); /* We gaan 6 portfolio items per pagina tonen */
?>

Dit zorgt direct al voor een belangrijk deel van het pagina template: eerst wordt de header aangeroepen, gevolgd door 6 items van het type portfolio. Nu moeten we de weergave van die portfolio items nog regelen. Dat doe je door de volgende code toe te voegen aan page-portfolio.php:

<div id="portfolio" class="pf">
<h2>Mijn projecten</h2>
<div class="pf">

<?php if (have_posts()) : while (have_posts()) : the_post(); ?>

	<?php
		$title= str_ireplace('"', '', trim(get_the_title()));
		$desc= str_ireplace('"', '', trim(get_the_content()));
	?>

	<div id="pf" class="item">
				<div class="img"><a title="<?=$title?>: <?=$desc?>" rel="lightbox[work]" href="<?php print  getportfolio_thumbnailurl($post->ID) ?>"><?php the_post_thumbnail(); ?></a></div>
				<p><strong><?=$title?>:</strong> <?php print get_the_excerpt(); ?> <a title="<?=$title?>: <?=$desc?>" rel="lightbox[work]" href="<?php print  getportfolio_thumbnailurl($post->ID) ?>">(lees meer)</a></p>
				<?php $site= get_post_custom_values('projectLink');
					if($site[0] != ""){

				?>
					<p><a href="<?=$site[0]?>" target="new">Bezoek deze website</a></p>

				<?php }else{ ?>
					<p><em>Geen link beschikbaar</em></p>
				<?php } ?>
			</div>

<?php endwhile; endif; ?>
</div>
</div>

<?php get_footer(); ?>

Nu dit eenmaal gedaan is kunnen we al eens kijken wat het resultaat hiervan is. In de WordPress backend zien we dat we bij het aanmaken van een nieuwe pagina het nieuwe ‘Portfolio’ type tegenkomen:

Kies het Portfolio sjabloon bij het maken van een nieuwe pagina
Dat is alles dat je hoeft te doen om je portfolio items te tonen, plus het aanmaken van een link in het menu natuurlijk. Snel even kijken wat hiervan dan het resultaat is op de website zelf.
Portfolio voorbeeld met custom post types
Dat ziet er al leuk uit! De opmaak moet nog wat verbeterd worden natuurlijk, maar de basis staat en het werkt. Ik verbeter de opmaak nog wat verder door wat CSS toe te voegen. Ik maak hiervoor een nieuw bestand aan: portfolio.css. In dat bestand neem je de volgende code op – waarbij je deze uiteraard kunt wijzigen al naar gelang de wijze waarop je e.e.a. wilt tonen.


#pf {
 width: 440px;
 float: left;
 overflow: hidden;
 padding: 10px;
 }

 .item{
 float: left;
 margin: 10px;
 width: 420px;
 background: #F7F7F7;
 -moz-border-radius: 7px;
 -webkit-border-radius: 7px;
 border-radius: 7px;
 text-align: center;
 -moz-box-shadow: 0px 0px 6px #999;
 -webkit-box-shadow: 0px 0px 6px #999;
 box-shadow: 0px 0px 6px #999;
 }

 .item p{ text-align: left; }
 .item p a{ text-align: left; font-weight: bold; }

 .item img{ margin-top: 5px; text-align: center; border: 5px solid #fff; max-width: 400px;}

 /* self-clear floats */

 .group:after {
 content: ".";
 display: block;
 height: 0;
 clear: both;
 visibility: hidden;
 }

Merk op dat je het portfolio.css bestand moet importeren in de style.css van je theme:

@import url("portfolio.css");

Het eindresultaat begint nu al echt ergens op te lijken. Ik ga mijn portfolio sectie nog wat verder uitbreiden en hem dan op deze website publiceren natuurlijk. De code van deze tutorial heb ik verwerkt in het theme dat je hier in z’n geheel kunt downloaden. Zie ook mijn artikel over een gratis vertaling van je WordPress theme.

Nederlands wordpress theme portfolio

Wil je meer weten over het maken van themes? Schrijf je dan ik voor de gratis WordPress Nieuwsbrief! Tegen het eind van het jaar zal ik een boek uitbrengen dat helemaal gaat over het maken en aanpassen van themes.

Was dit artikel nuttig?

Laat het ons weten en geef je rating!

Gemiddeld 0 / 5. Aantal stemmen: 0

Nog geen stemmen, wees de eerste die dit artikel waardeert!

19 thoughts on “Leer werken met WordPress Custom Post Types”

  1. Handige en duidelijke handleiding. Alleen heb ik het nog niet werkend. Ik heb je portfolio.css en portfolio-posttype.php gekopieerd en geplakt in een ander thema. In de functions.php van dit theme heb ik de regel require_once(‘portfolio-posttype.php’); toegevoegd, maar krijg elke keer een foutmelding. Ben ik een stap vergeten? Wat doe ik fout?

  2. Hoi Ferdi, het klinkt flauw, maar dat weet ik natuurlijk niet. Met alleen de melding ‘hij doet het niet’ komen we niet veel verder. Begrijp ik je goed dat je in het eerste gedeelte al vast loopt en bij het 2e deel (het maken vd page-portfolio.php) helemaal niet aankomt? Wat voor foutmelding krijg je en waar doet deze zich voor? In de WordPress frontend of backend?

  3. Hoi Robbert, ik heb je theme gedownload en hiervan de portfolio-posttype.php en portfolio.css in mijn eigen theme(map) geplaatst. Vervolgens heb ik in de functions.php de code require_once(‘portfolio-posttype.php’); geplaatst, maar zonde resultaat dus. Probleem doet zich meteen in de back-end voor.

    Voor de duidelijkheid, ik heb dus niet de stappen uitgevoerd zoals in de handleiding, maar gewoon je aanwezige php.bestanden uit je theme gebruikt.

  4. Hoi Robbert,

    Ik krijg deze foutmelding wanneer ik in het dashboard een post wil openen of toevoegen:

    Parse error: syntax error, unexpected T_REQUIRE_ONCE in /home/innovata/public_html/testomgeving/wp-content/themes/suffusion/functions.php on line 2

  5. Dag Robbert,

    zit volgens mij een foutje in de code op page-portfolio.php:
    get_post_custom_values(‘projLink’);

    moet zijn:
    get_post_custom_values(‘projectLink’);

    Bedankt voor je tutorial!
    Jim

  6. Wat als er meer berichten zijn.
    Met next page en previous page krijg ik die niet te zien.
    Hij blijft op de eerste pagina hangen

  7. Hallo Robbert,
    Ik heb een vraagje, misschien een enorme domme maar ik kom er niet uit 😉 Ik ben een site aan het maken in WordPress met op de homepage een portfolio. Nu wil ik eigenlijk wanneer je op een van de plaatjes van die portfolio klikt op de homepage, dat het linkt naar een pagina met een ‘andere’ portfolio maar ik krijg dat niet voor elkaar. Wanneer ik meerdere portfolioberichten toevoeg, vervalt gewoon de laatst toegevoegde op de homepagenen ik wil dat die blijft staan in ieder geval.
    Snap je wat ik bedoel? Misschien is de oplossing simpel, ik zou je eeuwig dankbaar zijn 😉

  8. Hoi,

    Er zit ’n fout in de code:

    Aangezien alle codes in het Engels staan beschreven, zal in dit stuk code ook alles in het Engels moeten staan. “Template Naam: Portfolio” is dus fout.
    De juiste code is: “Templater Name: Portfolio”

    Naam=Name

    Bespaar 2,5 uur van uw tijd met het prutsen met de custom post types en het opzoeken van de desbetreffende fout.

    Wellicht kan dit direct aangepast worden.

  9. jordy van de locht

    Robbert,

    Ik heb net alles ingevoerd en ik kan nu geen afbeeldingen meer uploaden. Wanneer ik een uitgelichte afbeelding wil toevoegen dan geeft hij een error: “An error occurred in the upload. Please try again later.” maar wanneer ik dan naar de media tab ga dan staat de afbeeldingen daar wel. Het heeft te maken met deze regel: wanneer ik deze weg doe dan werkt alles terug zoals ervoor.

    Zou je mij kunnen helpen. Bedankt!

    Jordy

  10. Hoi Robbert,
    Dank voor je tutorial, heel helder, en het werkt allemaal bij mij.
    Zou je kunnen uitleggen wat ik moet doen om de originele post te kunnen tonen ipv een link naar een website? Ik gebruik the_permalink, dat werkt wel, maar krijg vervolgens de melding dat de pagina niet wordt gevonden. Ik krijg het idee dat ik nog wat moet doen om de custom fields uberhaupt te kunnen tonen.
    Alvast bedankt!

    Rob

  11. Hallo,

    Even een vraagje naar aanleiding van de laatste berichten,

    Werkt deze tutorial nu wel? of geeft het nog steeds errors?
    Zou ik heel graag willen weten voor ik eraan begin namelijk…

    grt!

  12. Ik heb even de tutorial gevolgd en werkt nog steeds prima!
    Alleen de link krijg ik niet weergegeven :-((

  13. Hallo Robbert,

    Als ik de hieronder gegevens in een nieuw bericht met wordpress zet en eerst als concept opslaan dan werkt het wel. Als ik dit publiceer dan zie ik in tab “tekst”niet meer de opmaak. Hoe kan dat?

    Verder werkt het standaard in wordpress ook niet goed want dan zie ik alleen 1 regel naast het plaatje.

    Heb jij een goede tip om dit op te lossen?

    groet

    Wim ter Haar

    img {
    float: left;
    margin: 15px 15px 15px 15px;
    }

    In this example, the image will float to the right in the paragraph, and the text in the paragraph will wrap around the image.

    Lorem ipsum dolor sit amet, consectetur adipiscing elit. Phasellus imperdiet, nulla et dictum interdum, nisi lorem egestas odio, vitae scelerisque enim ligula venenatis dolor. Maecenas nisl est, ultrices nec congue eget, auctor vitae massa. Fusce luctus vestibulum augue ut aliquet. Mauris ante ligula, facilisis sed ornare eu, lobortis in odio. Praesent convallis urna a lacus interdum ut hendrerit risus congue. Nunc sagittis dictum nisi, sed ullamcorper ipsum dignissim ac. In at libero sed nunc venenatis imperdiet sed ornare turpis. Donec vitae dui eget tellus gravida venenatis. Integer fringilla congue eros non fermentum. Sed dapibus pulvinar nibh tempor porta. Cras ac leo purus. Mauris quis diam velit.

Geef een reactie

Het e-mailadres wordt niet gepubliceerd. Verplichte velden zijn gemarkeerd met *