Adding custom entry types to PivotX
September 2nd, 2010
A big advantage of WordPress over PivotX is the availability of custom entry types in WordPress. PivotX doesn’t have this (and here I should probably insert the word ‘yet’).
However, as always, nothing is impossible! We can make PivotX do what we want it to do with a little hacking in the core, and the help of the ‘Bonus Fields’ extension.
First of all we want to do some modifications to the PivotX backend. Of course this is not recommended, because when you upgrade to a newer version of PivotX, your mods will be overwritten. However, because the modifications are small, and only in one place, it should be fairly easy to make the modifications again after an upgrade.
In this example, we’re going to make a custom entry type called ‘Custom Entry’. To get a menu option for creating ‘Custom Entries’ in the backend, we need to edit the menu structure that is in the data.php file in the PivotX directory.
Around line 73 in this file, we have the following code:
array(
'sortorder' => 1000,
'uri' => 'entries',
'name' => __('Entries'),
'description' => __('Overview of Entries')
),
array(
'sortorder' => 2000,
'uri' => 'entry',
'name' => __('New Entry'),
'description' => __('Write and Publish a new Entry')
),
array(
'sortorder' => 3000,
'is_divider' => true
),
array(
'sortorder' => 4000,
'uri' => 'pagesoverview',
'name' => __('Pages'),
'description' => __('Overview of Pages')
),
array(
'sortorder' => 5000,
'uri' => 'page',
'name' => __('New Page'),
'description' => __('Write and Publish a new Page')
),
To create a menu entry for our ‘Custom Entry’, we have to add the following code right after the array for a ‘New Entry’, like so:
array(
'sortorder' => 2000,
'uri' => 'entry',
'name' => __('New Entry'),
'description' => __('Write and Publish a new Entry')
),
// create custom entry menu item
array(
'sortorder' => 2500,
'uri' => 'entry&entry_type=custom',
'name' => __('New Custom Entry'),
'description' => __('Write and Publish a new Custom Entry')
),
//end of custom entry menu item
array(
'sortorder' => 3000,
'is_divider' => true
),
For clarity: the new code is between “// create custom entry menu item” and “//end of custom entry menu item”.
To see if it works, let’s go to the PivotX backend, and look at the menu:
There you go: a brand new menu item!
Now of course this menu item needs to do something as well. In order to make this work, we need to make sure the ‘Bonus Fields‘ extension is installed first. After installing the extension, we need to create ourselves a bonus field called ‘entry_type’. For this you have to go to ‘Extensions -> Configure Extensions -> Bonus Fields’, and enter the data as shown in this screenshot:
The field can be ‘hidden’, because we don’t actually have to see it in the back-end. For testing purposes, you could make it a normal field, but if you don’t want users to get confused, you should probably hide it.
At this point we should also create a new category just for this type of entry. You’ll have to go to ‘Administration’ -> ‘Categories’ and click the ‘Create new Category’ button. We’ll call the category ‘custom’.
Next, we’re going to write a little hook-extension, that will do the following:
- Assign the category ‘Custom’ to our ‘Custom Entry’
- Add custom fields to our ‘Custom Entry’.
Create a file called ‘hook_customtype.php’ in the ‘extensions’ directory. The first part of the extension consists of comments, to identify the extension. I used the following code here, but you’re welcome to insert your own information (to be honest, I copied most of this from @Jadwigo anyway)
<?php // - Extension: Customtype extrafields // - Version: 0.1 // - Author: John Schop // - Email: john.schop at gmail.com // - Site: http://www.windmillwebwork.com // - Description: Add bonus fields to custom type entries. // - Date: 2010-09-02
The first thing to do is add a hook, so we can call a function when somebody edits an entry:
$this->addHook(
'entry_edit_beforeedit',
'callback',
'extraCustomCategory'
);
All this does is tell PivotX to call the function ‘extraCustomCategory’ as soon as somebody creates or edits an entry, and it will call the function before the entry is edited.
Now we need to create the function itself. The function will assign the value ‘custom’ to our ‘Entry Type’ custom field when you click the ‘New Custom Entry’ button in the top menu (the item we created when we started all this). It will also assign the ‘Custom’ category to these entries:
function extraCustomCategory(&$entry) {
global $PIVOTX;
//var_dump($entry);
if(isset($_REQUEST['entry_type']) && $_REQUEST['entry_type']=='custom') {
$entry['extrafields']['entry_type'] = 'custom';
}
// exit if not a custom entry
if($entry['extrafields']['entry_type'] != 'custom') { return; }
// add custom category
if(!in_array('custom', $entry['category'])){
$entry['category'][] = 'custom';
};
}
Remember, we are still adding all this code to our hook_customtype.php file!
Next, we are going to make sure that ‘Custom Entries’ actually have something unique that normal entries don’t have: some extra information!
If you’re still wondering how you can use this, consider the possibility that you want to add products to your website, with custom fields like ‘Price’, ‘Size’ and a picture of the product.
First, the hook, so PivotX knows where to put this extra stuff:
$this->addHook(
'in_pivotx_template',
'entry-introduction-before',
array('callback' => 'extraCustomFields' )
);
The above code makes sure that PivotX is going to execute whatever we write in the function ‘extraCustomFields’ before the ‘introduction’ part of our custom entry.
Assuming you wanted to add ‘Price’, ‘Size’ and a picture to your entry, the ‘extraCustomFields’ function should look like this:
function extraCustomFields($item) {
// exit if a not a custom entry
if($item['extrafields']['entry_type'] != 'custom') { return; }
$output = <<< EOM
<table class="formclass" border="0" cellspacing="0" width="650">
<tbody>
<tr><td colspan="3"><hr size="1" noshade="noshade" /></td></tr>
<tr>
<td width="140">
<label for="extrafield-price"><strong>Price:</strong></label>
</td>
<td width="510" colspan="2">
<input id="extrafield-price" name="extrafields[price]" value="%price%" type="text" />
</td>
</tr>
<tr>
<td width="140">
<label for="extrafield-size"><strong>Available sizes:</strong></label>
</td>
<td width="510" colspan="2">
<input id="extrafield-size" name="extrafields[size]" value="%size%" type="text" />
</td>
</tr>
<tr>
<td width="150">
<label for="extrafield-image"><strong>Product Image:</strong></label>
</td>
<td width="400">
<input id="extrafield-image" name="extrafields[image]" value="%image%" type="text" style="width: 400px;"/>
</td>
<td width="100" class="buttons_small">
<a href="javascript:;" onclick="openUploadWindow('%label1%', $('#extrafield-image'), 'gif,jpg,png');">
<img src='pics/page_lightning.png' alt='' /> %label2%
</a>
</td>
</tr>
<tr><td colspan="3"><hr size="1" noshade="noshade" /></td></tr>
</tbody>
</table>
EOM;
// For ease of use, just try to replace everything in $entry here:
foreach($item as $key=>$value) {
$output = str_replace("%".$key."%", $value, $output);
}
foreach($item['extrafields'] as $key=>$value) {
$output = str_replace("%".$key."%", $value, $output);
}
// Don't keep any %whatever%'s hanging around..
$output = preg_replace("/%([a-z0-9_-]+)%/i", "", $output);
return $output;
}
That is basically all the programming we have to do, but there is one important thing left: at the very end of our hook_customtype.php file, we need to type “?>” (of course without the quotes).
Now, in your backend, you should find a new extension in the list, that you of course will have to activate:
Now, to check if everything works, let’s create a new ‘Custom Entry’:
Ha! Apparently it works. Now if we save this entry, it should show up on the front page of our website (I used the Wichita template here):
Bummer…no custom fields anywhere. Of course not, because we need to add the custom stuff to our template! In your template, you could add something like this:
[[if $entry.extrafields.entry_type=='custom']] [[if $entry.extrafields.price!=""]] <div class="price">Price: [[ $entry.extrafields.price ]]</div> [[/if]] [[if $entry.extrafields.size!=""]] <div class="size">Sizes: [[ $entry.extrafields.size ]]</div> [[/if]] [[if $entry.extrafields.image!=""]] <div><img src="images/[[ $entry.extrafields.image ]]" /></div> [[/if]] [[/if]]
And that should do the trick:
Awesome!
If you want to create your own custom types of entries, feel free to use the source code.
Some additional notes and remarks:
- If the entry doesn’t show up on your frontpage at all, you probably forgot to add the ‘custom’ category to your weblog. You need to do this in ‘Administration’ -> ‘Weblogs’, then click ‘Edit’, choose the ‘Subweblogs’ tab, and add the ‘Custom’ category to the list of categories linked to your weblog. This is probably the most counter-intuitive thing in the PivotX backend, but it looks like we’ll have to live with it.
- Again, be careful when upgrading after you’ve done these mods. Everything will continue to work, but you will loose your ‘New Custom Entry’ menu item after an upgrade, unless you make the changes to data.php again.









cool!
I have a couple of comments, but first I must say you have done some nice work here.
1) Yes, custom entry types will be part of the PivotX core in the not too distant future. However, it will most likely only be supported for the MySQL database.
2) There is no need to modify the PivotX core – there is a “modify_pivotx_menu” hook. If you look at the Bonus Fields source code, you can see an example which is very close to what you want.
3) You have created what I would call “Simple Custom Entry Types”. I think I’ll take your code and make it a little bit more general and release it as a proper extension – if you don’t mind. (I’ll give you proper credit of course.) I think it will be a killer extension.
Thanks for the compliment Hans!
1. That’s good news…I hope it’s rather sooner than later, because this functionality is really powerfull.
2. I did not know that…is there a list of all available hooks?
3. I’d be honoured. Making a good admin interface here to add different types of fields is the key here. It would be nice if it could include somehting like a datepicker as well, I can see that used in creating ‘event’ type entries.