Using WordPress portfolio tags and types in a theme

I’ve been using the WordPress portfolio feature on my blog and website, but it turns out that portfolio tags are dealt with differently from post tags, as they are part of a custom content type with their own taxonomy.  I searched around for the theme code to insert a tag list but the best I could find was this post (which obviously worked at some point), but a bit of database examination showed that the name of the taxonomy must have changed since this post was written, and they are now named jetpack-portfolio-tag (and jetpack-portfolio-type for the type).

Therefore the code to insert a list of WordPress portfolio tags into a theme is:

<?php the_terms(get_the_ID(), 'jetpack-portfolio-tag', $before, $separator, $after); ?>

using the optional $before, $separator and $after parameters to taste.

Flextrine Tutorial – CRUD in a simple Flex 4 address book: Setting up the server

Introduction
Setting up the server
Creating the entities
Creating the database schema
Loading the entities
Creating new entities
Deleting entities
Updating entities
Conclusion

Before using Flextrine you need to do some groundwork to get your project ready.

  1. Download the latest version of Flextrine from http://code.google.com/p/flextrine2/downloads/list
  2. Install the Flextrine manager.  This is as simple as copying the manager directory from the Flextrine download into a web-accessible directory.  For the purposes of the tutorial I will assume that you have set the URL pointing at this document root as http://localhost/flextrinemanager.  Note that you will require mod_rewrite to be enabled on your webserver for the manager to function correctly.
  3. Install the Flextrine server side libraries.  These are contained in the flextrine/web/lib directory of the the Flextrine download.  All you need to do to install these is to copy flextrine/web/lib to a directory in your PHP include_path, or ammend the include_path to include the flextrine/web/lib directory.  Note that if you don’t want to change your include_path you can set it explicitly after the next step by uncommenting the $flextrineIncludePAth line in config.php of your project (see http://code.google.com/p/flextrine2/wiki/GettingStarted for more details).
  4. Install the latest version of Doctrine 2 from http://www.doctrine-project.org/projects/orm/download.  Doctrine 2 is the technology that Flextrine is based upon and required for its operation.  The easiest way to install Doctrine is to merely extract the package into flextrine/web/lib as this is already in your PHP include_path.  Alternatively you can add a new entry to your include_path pointing to Doctrine.
  5. Create an empty server-side Flextrine project.  The Flextrine download contains a blank project in flextrine/web/flextrineproject which will be your starting point.  Copy this to a new directory on your machine and make this directory web accessible.  For the purposes of this tutorial I will assume that you have set the URL pointing to this directory as http://localhost/contacts and will refer to the directory as the Flextrine server side component.
  6. Create a new MySQL database called contacts.
  7. In your Flextrine server side component open up config.php and set the database connection options in the $connectionOptions variable.

Note that next time you start a new Flextrine projects you only need to do steps 5 – 6 as steps 1 – 4 only need to be done once.

Now we are ready to use Flextrine!  The next step is to create some entities.

Flextrine Tutorial – CRUD in a simple Flex 4 address book: Introduction

Introduction
Setting up the server
Creating the entities
Creating the database schema
Loading the entities
Creating new entities
Deleting entities
Updating entities
Conclusion

UPDATED FOR FLEXTRINE 0.6.5!

After numerous requests I have finally sat myself down to write a basic tutorial for using Flextrine in a practical and simple Flex application.

What is Flextrine?

In a sentence, Flextrine is an open-source solution for reading and writing AS3 objects to and from a remote database.  Flextrine doesn’t really do anything that you couldn’t do by hand using PHP and AS3 code, but it removes most of the grunt work and standardises client-server database interactions.  All being well, database aware Flex applications coded using Flextrine are shorter, more readable and more maintainable.

Documentation for Flextrine is available in its Google Code wiki and its definitely worth having a skim through before beginning the tutorial.

What shall we build?

In this tutorial we are going to demonstrate some of Flextrine’s functionality by building a simple online contacts manager.  The application will allow us to create, edit and delete contacts, each of which simply have names and telephone numbers.  In order to demonstrate some of Flextrine’s associations we will also allow the user to put contacts into groups.

Note that the purpose of this tutorial is to demonstrate Flextrine rather than Flex, so we won’t be using any frameworks (apart from Flex itself) and where there is a choice between an elegant programming solution and just keeping it simple we’ll be going for the simpler option 🙂

Requirements

To run through this tutorial you will need the following:

  • Flex SDK 4 (free from Adobe)
  • A nice Flex IDE – I personally use the wonderful FlashDevelop, but Flash Builder 4 will do just as well
  • A web server running PHP 5.3+ and MySQL (WAMP for Windows and MAMP for OSX are good choices)
  • Download the complete source code for the tutorial and save yourself tedious typing!  This does not include the Flextrine AS3 code so you will need to add the source code or SWC to your classpath manually before compiling.

Lets begin by installing Flextrine and its dependencies.

Flextrine chosen for elevator pitch at Flash on the Beach 2010!

My open source ORM project Flextrine has been chosen as one of 20 projects to present at this years Flash on the Beach, in Brighton this September.  I get three hectic minutes to showcase Flextrine and try and demonstrate what it can do 🙂

If you find yourself at Flash on the Beach this year come down and listen!

http://www.flashonthebeach.com/sessions/index.php?pageid=2999
http://code.google.com/p/flextrine2/

Flextrine 0.5 released!

I have released the first public version of Flextrine.  Its actually pretty feature rich, and I will be focusing mainly on bug fixes and stability as reports start to come back from the community leading up to the main release on 1st September.

Major features that have made it into 0.5:

  • Entities and the entity manager
  • Single and collection associations
  • The Flextrine Manager
  • AS3 code generation
  • Lazy loading, requireOne and requireMany
  • Full Flex databinding
  • DQL queries

Flextrine can be downloaded from Google Code at http://code.google.com/p/flextrine2/  Please try it out and log any issue you might find in Google Code.

How to stop SWFs caching in the browser once and for all

As Flash and Flex developers know all too well, browsers have a habit of caching SWFs so that when you put up a new version it doesn’t always show up on client machines.  There are two classic ways to get around this – either by manually clearing your cache (and telling your clients to do the same) or by appending a random number to the end of the filename as a parameter which is then ignored by the application but fools the browser into thinking that the file has changed.  The first method is unreliable and the second method causes the SWF to reload every time you visit the page (even if it hasn’t changed) which munches up your bandwidth and your time.

As it turns out, there is a third and far superior way!  With a tiny bit of PHP in your embed code you can make browsers refresh the SWF only when it has changed.  Note that this uses the SWFObject library, but would work equally well with any embedding method.

   1: swfobject.embedSWF("MySWF.swf?version=<?php echo filemtime('MySWF.swf'); ?>", "myDiv", "100%", "100%", "10.0.0");

It works by using the file modification timestamp of the swf as the version number with the result that browsers will refresh their cached copy if and only if you replace the swf with a new version.  Simple and extremely useful!

Silverstripe – overview and impressions

I have recently been doing quite a lot of work with Silverstripe, a new(ish) open-source PHP MVC framework with an integrated CMS developed by a company in New Zealand.  Silverstripe has been gaining some decent support over the last year due to its interface, usability and extensibility.

How does it work?

Silverstripe is made up of two elements.  The first, and most important, is Sapphire.  This is a PHP based MVC framework, similar in many ways to Ruby on Rails.  It provides support for views (via a custom templating language), controllers and models.  Models have a number of special static attributes which provide Sapphire with information about the model; for example, which fields should exist in the database for the model and their datatypes are contained in the $db attribute, one-to-many relationships are defined in $has_many, and many more.  Sapphire then implements a database rebuild task which brings the database up to date with any changes in the code; this can either be run in the browser or from the command line for use in deployment and build scripts.  On a lower level Sapphire’s base Object.php class implements a kind of PHPified mixin system using the concept of extensions.  Unfortunately PHP isn’t really the best language for this kind of thing, but given the limitations and as long as you remember to follow some rules this is a fairly powerful system for extending and decorating objects.

The second part of the system is the Silverstripe CMS module.  This is a web application built on Sapphire (just as any site you create will be another web application built on Sapphire) which implements a very nice AJAX based CMS for your site with a tree on the left hand side and a content area on the right hand side.  The basic CMS is sufficient for most simple sites, but it can be extended hugely using extensions, decorators and plugins.

Silverstripe

The CMS module uses the object extension system to add a number of CMS specific special attributes to the model such as $allowed_children, $icon and $default_child which set various properties and permissions on the tree when that particular model is used in the CMS, and you can override getCMSFields() in the model to specify which fields are editable for a particular page, what kind of editors to use and which database fields they link to.  For example, the following in a Silverstripe model will create a natty CMS editor with a checkbox, title and HTML editor (using tiny_mce2) which automatically populates and saves to the database.  Nice eh?

   1: static $db = array(
   2:     'YesNo' => 'Boolean',
   3:     'Title' => 'Text',
   4:     'ContentHTMLText' => 'HTMLText',
   5: );
   6:
   7: function getCMSFields() {
   8:     $fields = parent::getCMSFields();
   9:
  10:     $fields->addFieldsToTab('Root.Content.Main', array(
  11:         new CheckboxField('YesNo', 'Check for yes'),
  12:         new TextField('Title', 'Enter title'),
  13:         new HTMLEditorField('Content')
  14:     ));
  15: }

Views and the templating language

Sapphire implements its own basic templating language (in *.ss files).  Its quite limited when compared to a more mature product like Smarty, but most of the time it is sufficient for what you will need.  You can embed another templates within a template, and access methods in the controller.  Occasionally this forces you to put logic in the controller or model that really belongs in the view, but conversely it stops you overloading your views with logic that doesn’t belong there 🙂

Impressions

Silverstripe is still a fairly young system and there are a few middling to serious problems with it.  Some specific things are problems with using the draft/published versioning system together with has_many relationships, issues with deployment when using staging and live servers, lack of hierarchical URLs and a number of other things that pop up from time to time.  However, we have just deployed a global Flash/HTML solution for a large company with multiple content editors; most of the way has been plain sailing and we never encountered an issue with Silverstripe that couldn’t be worked around one way or another.

In summary Sapphire/Silverstripe is a great piece of software and I recommend it to all web developers everywhere!  Its open source so it will continue to be improved by the community and I have no doubt that Silverstripe’s major problems will be addressed in the next few iterations.  The official ‘Silverstripe book’ has just been released in English which will no doubt help bring the system to a larger market.

Silverstripe (commercial) – www.silverstripe.com

Silverstripe (open source) – www.silverstripe.org

Silverstripe book (Amazon UK) – http://www.amazon.co.uk/SilverStripe-Complete-Guide-Development-Wiley/dp/0470681837

Writing private attributes to a database using AMF in AS3 (IExternalizable)

Yesterday may have been one of the most frustrating days of my entire career. The brief – simple; take a bunch of classes acting as models (with a single top-level model containing all others in a tree hierarchy) and write their contents to a database. Client-side technology is Flash CS3 with Actionscript 3, server-side technologies are PHP 5 and MySQL. After having a look at the problem I decided that the quickest and most elegant way of achieving this would be to use Flash Remoting with AMFPHP on the server and to use custom class mapping to effectively pass the top level model and all its children to the server so they arrive with the same class structure as they left.

The code to make a Flash Remoting call is pretty standard stuff (note that this assumes the existence of onResult and onFault handlers):

   1: var myService:NetConnection = new NetConnection();
   2: myService.objectEncoding = ObjectEncoding.AMF0;
   3: myService.connect("http://localhost/amfphp/gateway.php");
   4:
   5: var responder = new Responder(onResult, onFault);
   6: myService.call("MyService.write_data", responder, myDataModel);

Once I’d implemented this along with a simple AMFPHP service containing the write_data function I was surprised to find that no data was getting passed to the server. After a lot of fiddling around I discovered the reason why:

By default AMF only encodes public attributes.

This is pretty annoying since no programmer worth their salt is going to be making all the attributes of their model public. That’s fine, thought I, I’ll implement some public getters:

   1: class MyDataModel {
   2:     private var myInt:uint;
   3:     private var myString:String;
   4:
   5:     public function get dbMyInt():uint {
   6:         return myInt;
   7:     }
   8:
   9:     public function get dbMyString():String {
  10:         return myString;
  11:     }
  12: }

Beautiful. Except for one thing.

By default AMF only encodes real attributes.

So this doesn’t work at all – the getters are completely ignored and still no data is passed to the server.

The ‘official’ solution

Finally I hit upon the real solution – use the IExternalizable interface to override the default behaviour of the AMF encoder and select what you want to encode/decode. Note that in order to use this you need to set the object encoding to AMF3 with myService.objectEncoding = ObjectEncoding.AMF3 (and you need to use AMFPHP 1.9+ as earlier versions don’t support AMF3).

   1: class MyDataModel implements IExternalizable {
   2:     private var myInt:uint;
   3:     private var myString:String;
   4:
   5:     public function writeExternal(output:IDataOutput) {
   6:         output.writeInt(myInt);
   7:         output.writeUTF(myString);
   8:     }
   9:
  10:     public function readExternal(input:IDataInput) {
  11:         myInt = input.readInt();
  12:         myString = input.readUTF();
  13:     }
  14: }

Perfect, except for one thing… as soon as you implement IExternalizable AMFPHP no longer works, giving the classic NetConnection.Call.BadVersion – and no amount of fiddling seems to fix it. In desperation I turned to WebORB PHP, but it has the same problem (see this forum post) and I didn’t have time to properly work out SabreAMF. From reading around various forums and blogs it appears that IExternalizable works fine with BlazeDS, but I have seen no reports of it working with anything else.

A working solution

By this point I’d pretty much given up doing it ‘properly’; the job needed to get done and this had taken far too long already. I created a class that acts as a superclass for all models:

   1: class SerializableModel {
   2:     public function toObject():Object {
   3:         return new Object();
   4:     }
   5: }

By making all classes override this function explicitly adding their private attributes we circumvent the problems with IExternalizable and end up with an associative array on the PHP side which we can iterate through. Unfortunately this doesn’t allow us to map the classes to equivalent PHP classes on the server, but this does at least get the job done.

   1: class MyDataModel extends SerializableModel {
   2:     private var myInt:uint;
   3:     private var myString:String;
   4:
   5:     public override function toObject():Object {
   6:         var object:Object = super.toObject();
   7:
   8:         object.myInt = myInt;
   9:         object.myString = myString;
  10:
  11:         return object;
  12:     }
  13:

  15: }

Finally in the remote method call we pass the object constructed by this function using:

   1: : myService.call("MyService.write_data", responder, myDataModel.toObject());

A better solution?

I’d love to hear one! Please post comments with any suggestions or ideas on how to do this better. Even better, if anyone knows how to patch AMFPHP 1.9 to accept AMF messages constructed with the IExternalizable interface I would love to see it.