Global navigation

   Documentation Center
   eZ Studio & eZ Platform
     User Manual
     Technical Manual
   eZ Publish 4.x / legacy

eZ Publish (5.x)

eZ Publish 5.x | For eZ Platform & eZ Studio topics see Technical manual and User manual, for eZ Publish 4.x and Legacy topics see eZ Publish legacy

Versions Compared


  • This line was added.
  • This line was removed.
  • Formatting was changed.
Comment: Migrated to Confluence 5.3


The public API will give you an easy access to the eZ Publish content repository. This repository is the core component that manages content, locations (former Nodesnodes in eZ Publish 4.x), sections, content types (former Content Classes in eZ Publish 4.x), users, user groups, users and roles. It also provides a new, clear interface for plugging in custom field types (former Datatypesdatatypes in eZ Publish 4.x).

The public API is built on top of a layered architecture, including a new persistence layer for abstracting the storage functionalitypersistence API that abstracts storage. By using the public API, you are sure that your applications code will be forward compatible with future releases based on enhanced,   scalable and high-performance storage engines. Applications based on the public API are also fully backwards compatible by using the included storage engine based on the current kernel and database model.

Receipt 1 - Setting up a sample commandline symfony bundle which uses the public API

This receipt shows how to setup a simple symfony bundle with a commandline script using the public API. The command is executable within the app/console and dumps a content object for a given content id.

Go to the eZ publish installation

cd <ezpublish installation root>

Generate a new Bundle

php app/console generate:bundle

Now follow the instructions. This will create a bundle eZ/Publish/Bundle/CookBookBundle in the src directory of the installation root.




Code Block
  Welcome to the Symfony2 bundle generator  

Your application code must be written in bundles. This command helps
you generate them easily.

Each bundle is hosted under a namespace (like Acme/Bundle/BlogBundle).
The namespace should begin with a "vendor" name like your company name, your
project name, or your client name, followed by one or more optional category
sub-namespaces, and it should end with the bundle name itself
(which must have Bundle as a suffix).

See for more
details on bundle naming conventions.

Use / instead of \  for the namespace delimiter to avoid any problem.

Bundle namespace: eZ/Publish/Bundles/CookbookBundle

In your code, a bundle is often referenced by its name. It can be the
concatenation of all namespace parts but it's really up to you to come
up with a unique name (a good practice is to start with the vendor name).
Based on the namespace, we suggest eZPublishBundlesCookbookBundle.

Bundle name [eZPublishBundlesCookbookBundle]: 

The bundle can be generated anywhere. The suggested default directory uses
the standard conventions.

Target directory [.../ezpublish5/src]: 

Determine the format to use for the generated configuration.

Configuration format (yml, xml, php, or annotation) [annotation]: yml

To help you get started faster, the command can generate some
code snippets for you.

Do you want to generate the whole directory structure [no]? yes

  Summary before generation  

You are going to generate a "eZ\Publish\Bundles\CookbookBundle\eZPublishBundlesCookBookBundle" bundle
in ".../ezpublish5/src/" using the "yml" format.

Do you confirm generation [yes]? yes

  Bundle generation  

Generating the bundle code: OK
Checking that the bundle is autoloaded: OK
Confirm automatic update of your Kernel [yes]? yes  
Enabling the bundle inside the Kernel: OK
Confirm automatic update of the Routing [yes]? yes
Importing the bundle routing resource: OK

  You can now start using the generated code!  




Add a Command directory to the bundle

cd <ezpublish installation root>/eZ/Publish/Bundle/CookbookBundle

mkdir Command

add the following class file CookbookCommand.php in the directory Command


Code Block
titlemy first command
 * File containing the CookbookCommand class.
 * @copyright Copyright (C) 2012 eZ Systems AS. All rights reserved.
 * @license GNU General Public License v2
 * @version //autogentag//
namespace eZ\Publish\Bundle\CookbookBundle\Command;

use Symfony\Bundle\FrameworkBundle\Command\ContainerAwareCommand;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputOption;

class CookbookCommand extends ContainerAwareCommand
    protected function configure()
		// define a new app console command 'cookbook:run' which takes one argument mapped to contentId
		 $this->setName( 'cookbook:run' )
                       new InputArgument( 'contentId', InputArgument::REQUIRED, 'An existing content id' )

    protected function execute( InputInterface $input, OutputInterface $output )
	    // fetch the command line argument
	    $contentId = $input->getArgument( 'contentId' );

        // get the repository from DI container
        $repository = $this->getContainer()->get( 'ezpublish.api.repository' );
        // get the content service from the repository
        $contentService = $repository->getContentService();
             // call loadContentInfo and print out
             print_r( $contentService->loadContentInfo( $contentId ) );
        catch( \eZ\Publish\API\Repository\Exceptions\NotFoundException $e )
            $output->writeln( "No content with id $contentId" );


run f.e.

php app/console cookbook:run  57

Receipt 2 - Creating a content type group and a simple content type

Code Block
// start a transaction
    // create a new content type group
    $contentTypeGroupInput = new ezp\Content\Type\Group\Concrete();
    $contentTypeGroupInput->identifier = "API_ContentTypeGroup";
    // multi language names and description are supported in future
    // due to a bug it has to be provided by now for names
    $contentTypeGroupInput->name = array(
        'eng-GB' => ('API_CreateGroupTest'),
        'always-available' => 'eng-GB'
    // create the group 
    $contentTypeGroup = $contentTypeService->createGroup(
    // create a new content type
    $contentTypeInput = new ezp\Content\Type\Concrete();
    $contentTypeInput->identifier = "NewContentType";
    // thiss will be possible in upcoming builds
    // $contentType->remoteId = "myRemoteId-1234567890";
    $contentTypeInput->defaultAlwaysAvailable = true;
    $contentTypeInput->description = array(
        'eng-GB' => ( 'This is a new content type' ),
        'always-available' => 'eng-GB'
    $contentTypeInput->isContainer = false;
    $contentTypeInput->name = array(
        'eng-GB' => ( 'NewContentType' ),
        'always-available' => 'eng-GB'
    $contentTypeInput->nameSchema = "<name>";
    $contentTypeInput->urlAliasSchema = "<name>";
    // has to be changed to a language code not id
    $contentTypeInput->initialLanguageId = 2;
    $fields = array();
    // add field definitions
    $fieldDefinition = new FieldDefinition($contentType, "ezstring");
        new \ezp\Content\FieldType\TextLine\Value( "New Name" )
    $fieldDefinition->identifier = "name";
    $fieldDefinition->name = array(
        'eng-GB' => ( 'NameField' ),
        'always-available' => 'eng-GB'
    $fieldDefinition->isRequired = true;
    $fieldDefinition->isSearchable = true;
    $fieldDefinition->fieldGroup = "TestCategory";
    $fieldDefinition->isTranslatable = true;
    $fieldDefinition->position = 1;
    // add a string length validator         
    $strLenValidator = new StringLengthValidator();
            array( 'maxStringLength' => 20, 'minStringLength' => 4 )
    $fields[] = $fieldDefinition;
    // add second field definitions
    $fieldDefinition = new FieldDefinition($contentType, "ezinteger");
        new \ezp\Content\FieldType\Integer\Value( 2 )
    $fieldDefinition->identifier = "Number";
    $fieldDefinition->name = array(
        'eng-GB' => 'NumberField',
        'always-available' => 'eng-GB'
    $fieldDefinition->isRequired = false;
    $fieldDefinition->isSearchable = false;
    $fieldDefinition->fieldGroup = "MetaInfo";
    $fieldDefinition->isTranslatable = false;
    $fieldDefinition->position = 2;
    $fields[] = $fieldDefinition;
    // creates the content type in the given group and fields and publishes it
    $contentType = $contentTypeService->createAndPublish(
        $contentType, array( $contentTypeGroup ), $fields
    // add a content object of type NewContentType
catch(Exception $e) 
    // do handling here


Receipt 3  Update content type

This receipt shows how to read and update a content type
$contentType = $contentService->loadByIdentifier("NewContentType");


About this Cookbook

The objective of this Public API Cookbook is to progressively guide you through useful, everyday business logic, using the API in concrete recipes: obtaining a Location from a Content, fetching a set of Content, creating a User, and so on.

For each recipe, newly introduced elements will be explained in detail, including the required API components (services, value objects...). 


Did we forget an important recipe ?

Let us know in the comments.

Suggested tools

In addition to this cookbook, we strongly recommend that you use a full featured PHP IDE, such as Eclipse or PhpStorm. It will provide you information on every piece of code you use, including objects and classes documentation. We have paid very careful attention to PHPDoc throughout this API, and such a tool is a very valuable help when using this API.

On top of this, generated public API documentation can be found online, in various formats:

Children Display