ez.no / exponential / documentation / development / extensions / datatypes / new datatype
When you are creating or editing a class object, you should decide which datatypes are going to be used by your attributes. Although the datatypes that come with Exponential are powerful enough for creating complex content classes, you might still need to create your own datatypes for specific cases. Creating new datatypes requires having some basic knowledge of how Exponential datatypes work and which classes are necessary to be changed or added. In the following tutorial, how to create a new datatype is shown step by step using the datatype Email as an example. The Email datatype is used to save email address and implements some check rules to verify that input email is of correct format.
We start off by creating an extension called email by creating the email/ directory under the extension/ directory. To make the datatype Email, you should first create the folder ezemail/ under extension/email/datatypes/ then create the file called ezemailtype.php under the newly created folder. Note that the name of the folder and PHP file is important since it will be used to locate the file. The basic structure is that if you added a datatype x, it should be stored like this: extension/myextension/datatypes/ezx/ezxtype.php.
All datatype files should inherit from the file ./kernel/classes/ezdatatype.php and implement some functions which the super class has defined but not implemented. Let's work through the code of ezemailtype.php to see how this class was implemented.
<?php // Include the super class file include_once( "kernel/classes/ezdatatype.php" ); // Include the file which will be used to validate email include_once( "lib/ezutils/classes/ezmail.php" ); // Define the name of datatype string define( "EZ_DATATYPESTRING_EMAIL", "ezemail" ); class eZEmailType extends eZDataType { /*! Construction of the class, note that the second parameter in eZDataType is the actual name showed in the datatype dropdown list. */ function eZEmailType() { $this->eZDataType( EZ_DATATYPESTRING_EMAIL, "Email" ); } /*! Validates the input and returns true if the input was valid for this datatype. Here you could add special rules for validating email. Parameter $http holds the class object eZHttpTool which has functions to fetch and check http input. Parameter $base holds the base name of http variable, in this case the base name will be 'ContentObjectAttribute'. Parameter $contentObjectAttribute holds the attribue object. */ function validateObjectAttributeHTTPInput( &$http, $base, &$contentObjectAttribute ) { if ( $http->hasPostVariable( $base . '_data_text_' . $contentObjectAttribute->attribute( 'id' ) ) ) { $email =& $http->postVariable( $base . '_data_text_' . $contentObjectAttribute->attribute( 'id' ) ); $classAttribute =& $contentObjectAttribute->contentClassAttribute(); if ( $classAttribute->attribute( "is_required" ) == true ) { if ( $email == "" ) { $contentObjectAttribute->setValidationError( ezi18n( 'content/datatypes', 'A valid email account is required.', 'eZEmailType' ) ); return EZ_INPUT_VALIDATOR_STATE_INVALID; } } if ( $email != "" ) { $isValidate = eZMail::validate( $email ); if ( ! $isValidate ) { $contentObjectAttribute->setValidationError( ezi18n( 'content/datatypes', 'Email address is not valid.', 'eZEmailType' ) ); return EZ_INPUT_VALIDATOR_STATE_INVALID; } } } return EZ_INPUT_VALIDATOR_STATE_ACCEPTED; } /*! Fetches the http post var string input and stores it in the data instance. An email could be easily stored as variable characters, we use data_text filed in database to save it. In the template, the textfile name of email input is something like 'ContentObjectAttribute_data_text_idOfTheAttribute', therefore we fetch the http variable '$base . "_data_text_" . $contentObjectAttribute->attribute( "id" )' Again, parameters $base holds the base name of http variable and is 'ContentObjectAttribute' in this example. */ function fetchObjectAttributeHTTPInput( &$http, $base, &$contentObjectAttribute ) { if ( $http->hasPostVariable( $base . "_data_text_" . $contentObjectAttribute->attribute( "id" ) ) ) { $data =& $http->postVariable( $base . "_data_text_" . $contentObjectAttribute->attribute( "id" ) ); $contentObjectAttribute->setAttribute( "data_text", $data ); } return false; } /*! Store the content. Since the content has been stored in function fetchObjectAttributeHTTPInput(), this function is with empty code. */ function storeObjectAttribute( &$contentObjectattribute ) { } /*! Returns the content. */ function &objectAttributeContent( &$contentObjectAttribute ) { return $contentObjectAttribute->attribute( "data_text" ); } /*! Returns the meta data used for storing search indices. */ function metaData( $contentObjectAttribute ) { return $contentObjectAttribute->attribute( "data_text" ); } /*! Returns the text. */ function title( &$contentObjectAttribute ) { return $contentObjectAttribute->attribute( "data_text" ); } } eZDataType::register( EZ_DATATYPESTRING_EMAIL, "ezemailtype" ); ?>
As the code illustrates, it must include the PHP file ezdatatype.php and inherit from eZDataType. The class should implement the functions validateObjectAttributeHTTPInput, fixupObjectAttributeHTTPInput, fetchObjectAttributeHTTPInput and storeObjectAttribute. The function validateObjectAttributeHTTPInput, which validates the datatype input, and the function fetchObjectAttributeHTTPInput, which gets the datatype input and stores it, are the most important functions that need to be rewritten for every new datatype. Other functions may have the same content. At the end of the file, the new datatype should be registered in the system by calling the register method in the class eZDataType.
In this example, the following line
eZDataType::register( EZ_DATATYPESTRING_EMAIL, "ezemailtype" );
was added.
Not every datatype needs to have a template file in class level since most datatypes can use standard UI supplied with Exponential. It is only necessary when the datatype has specific constraints that need to be defined during class editing. Examples are setting a default value for the datatype, adding customer action buttons, etc. If so, the datatype file should implement the functions storeClassAttribute, validateClassAttributeHTTPInput, fixupClassAttributeHTTPInput and fetchClassAttributeHTTPInput which are defined in the super class ezdatatype.php. These functions deal with how to fetch and validate input and then store it in the database. Note that the template file should be located at extension/myextension/design/standard/templates/class/datatype/edit/ezx.tpl. The datatype Email does not have a specification in class level and therefore nothing needs to be done in this case.
For every datatype, two template files must to be added. One template file for content object editing and one for content object viewing. In this example, we add one ezemail.tpl (shown below) under extension/email/design/standard/templates/content/datatype/edit/. This is just a normal text field with corresponding name we defined in eZEmailtype.php. Users will use this text field to edit or input email address.
<input type="text" size="10" name="ContentObjectAttribute_data_text_{$attribute.id}" value="{$attribute.data_text}" />
The second ezemail.tpl is added under extension/email/design/standard/templates/content/datatype/view/, this template file will show the result of the saved email address.
{$attribute.data_text}
The last step is to add the newly created datatype to the content.ini file so it will be displayed in the datatype dropdown list, and add the design directory. Open/create the content.ini.append file under extension/myextension/settings/ with a text editor and insert this:
[DataTypeSettings] ExtensionDirectories[]=myextension AvailableDataTypes[]=ezemail
Open extension/myextension/settings/design.ini.append and add :
[ExtensionSettings] DesignExtensions[]=myextension
In order to be able to use the newly created extension, you need to activate it.
From the admin interface go to the set-up tab, Extension configuration (Avanced), then activate extension.
You can check the result by refreshing your browser and then go to the class editing page. If everything goes fine, you should find Email on the drop-down list.
In this tutorial, a simple datatype Email, which uses only one field in the database to store its content, was created. To create more complex datatypes, extra tables may need to be added and extra classes may need to be written. Please refer to the eZEnum type for more detail about how complex datatypes can be created.
Log in or create a user account to comment.
Comments
Typo in code sample
Roger Schmidt
Thursday 07 September 2006 12:39:18 am
Attention, in code sample of this chapter (ezemailtype.php) there is a typo:
The letter A in parameter $contentObjectattribute should be upper case, thus $contentObjectAttribute !
This is important, if you are using this function in your own datatype (see http://ez.no/community/forum/deve...stions_concerning_object_generation).
Regards,
Roger
function return value
Remco Wulms
Friday 11 February 2005 3:39:30 pm
within the if statement of the function fetchObjectAttributeHTTPInput.
Missing Step 4.5: Don't forget to enable your templates
Joel Hardi
Monday 03 May 2004 11:25:10 pm
[ExtensionSettings]
DesignExtensions[]=myextension
Otherwise, the custom datatype may not show up on edit forms -- for instance data_text types such as e-mail addresses default to a hidden form field, which obviously isn't any good for data entry!
datatype troubles / hints
Georg Franz
Saturday 28 February 2004 2:35:17 am
I spent some hours to find out, what is going wrong with my installation. I am using two self created datatypes which worked before, but since I've upgraded to 3.4-alpha1 they failed with fatal erros. Or to say it in a better way: The loading of the datatypes failed because the system couldn't find the files anymore.
I made a small error which has an great impact.
The ezdatatype class tried to load the file "ezgwftextlinetypetype.php" in my extension dir. which doesn't exist. The filename is ezgwftextlinetype.php. I searched all files to find out why (the hell) the system is searching after "*typetype.php" instead of "*type.php". Finally I found my error:
The first line of my custom datatype was:
define( 'EZ_DATATYPESTRING_GWFTEXTLINE', 'ezgwftextlinetype' );
and the system stored this name in the db (table ezcontentclass_attribute).
After changing the table-entry and the first line to
define( 'EZ_DATATYPESTRING_GWFTEXTLINE', 'ezgwftextline' );
it worked again.
The very strange thing: As I said in the former system this user-error won't have any effect and my custom datatype worked.
Kind regards,
Emil.
Step 6: activate the extension
Xavier DUTOIT
Tuesday 03 February 2004 12:19:49 pm
In order to be able to use the newly created extension, you need to activate it.
From the admin interface go to the set-up tab, Extension configuration (Avanced), then activate extension.