Add a new XML output format

Hello everyone,
I would like to add a new output format for the Omeka items located in a particular collection containing customized item types (with EAC-CPF metadata set).
My purpose is to export these Omeka items as EAC-CPF/XML files at the item level.
I have seen this use case https://omeka.org/codex/Plugin_Use_Cases/Add_a_New_Output_Format and this previous post http://omeka.org/forums-legacy/topic/plugin-use-case-add-new-output-format-for-20.
As I’m not exactly a developer, I’m a bit confused about how to adapt this case.
Is there any simple use case for Omeka 2.x I’m missing? Does anyone know a model plugin I can customize or a best practice for that?

The documentation for action_context and response_context shows a basic example of how to use them to create a new output format. Those basically replace steps 2 and 3 in the use case you linked to. Step 4 is pretty much the same – that’s where you create a view that actually constructs your XML.

I don’t know of a minimal model plugin aside from those off the top of my head.

Hi Patrick, thanks for your help.
Until now I get no output.
Here are my files (steps 1 to 3) :

plugin.ini
[info] name="ExportEacCpf" author="Nobody" description="exportxml" link="*" omeka_minimum_version="2.0" omeka_tested_up_to="2.4" version="0.1" tags="visualization, eaccpf"

plugin.php
<?php class ExportEacCpf extends Omeka_Plugin_AbstractPlugin { protected $_filters = array('define_action_context', 'define_response_contexts'); public function filterDefineActionContext($contexts, $args){ if($args['controller'] instanceof ItemsController) { $contexts['show'][] = 'eaccpf'; } return $contexts; } public function filterDefineResponseContexts($contexts) { $contexts['eaccpf'] = array('suffix' => 'eaccpf','headers' => array('Content-Type' => 'application/xml')); return $contexts; } } ?>

And the screen error I get

Bad on us…the documentation was wrong. I pushed up a change, but not sure how long it will take to update on the readthedocs site.

The wrong things are:

define_action_context should be action_contexts (note the s)
define_response_contexts should be response_contexts

The names of the functions change accordingly: filterResponseContexts and filterActionContexts

A plugin that does similar things is Geolocation. It sets up KML output for building the maps using the same system, so you’ll see the same filters defined, and the output in views/shared/browse.kml.php

Apologies for the wrongness in the documentation.

Thanks Patrick.
I modified the plugin.php but I get no output and the same error.
Any other suggestion?

Maybe rename plugin.php to ExportEacCpfPlugin.php

If you can copy-paste the text of the error, that’ll also help track things down. Might also be worth posting the current code for the renamed php file.

Done.
That’s the ExportEacCpfPlugin.php

<?php class ExportEacCpf extends Omeka_Plugin_AbstractPlugin { protected $_filters = array('action_contexts', 'response_contexts'); public function filterActionContexts($contexts, $args){ if($args['controller'] instanceof ItemsController) { $contexts['show'][] = array('eaccpf'); } return $contexts; } public function filterResponseContexts($contexts) { $contexts['eaccpf'] = array('suffix' => 'eaccpf','headers' => array('Content-Type' => 'text/xml')); return $contexts; } } ?>

And the text of the error

Zend_Controller_Action_Exception
Context "eaccpf" does not exist

exception 'Zend_Controller_Action_Exception' with message 'Context "eaccpf" does not exist' in /var/www/html/v1/application/libraries/Zend/Controller/Action/Helper/ContextSwitch.php:532
Stack trace:
#0 /var/www/html/v1/application/libraries/Zend/Controller/Action/Helper/ContextSwitch.php(1239): Zend_Controller_Action_Helper_ContextSwitch->hasContext('eaccpf', true)
#1 /var/www/html/v1/application/libraries/Zend/Controller/Action/Helper/ContextSwitch.php(257): Zend_Controller_Action_Helper_ContextSwitch->hasActionContext('show', 'eaccpf')
#2 /var/www/html/v1/application/libraries/Omeka/Controller/AbstractActionController.php(475): Zend_Controller_Action_Helper_ContextSwitch->initContext()
#3 /var/www/html/v1/application/libraries/Omeka/Controller/AbstractActionController.php(72): Omeka_Controller_AbstractActionController->_setActionContexts()
#4 /var/www/html/v1/application/libraries/Zend/Controller/Dispatcher/Standard.php(281): Omeka_Controller_AbstractActionController->__construct(Object(Zend_Controller_Request_Http), Object(Zend_Controller_Response_Http), Array)
#5 /var/www/html/v1/application/libraries/Zend/Controller/Front.php(954): Zend_Controller_Dispatcher_Standard->dispatch(Object(Zend_Controller_Request_Http), Object(Zend_Controller_Response_Http))
#6 /var/www/html/v1/application/libraries/Zend/Application/Bootstrap/Bootstrap.php(105): Zend_Controller_Front->dispatch()
#7 /var/www/html/v1/application/libraries/Zend/Application.php(384): Zend_Application_Bootstrap_Bootstrap->run()
#8 /var/www/html/v1/application/libraries/Omeka/Application.php(79): Zend_Application->run()
#9 /var/www/html/v1/index.php(23): Omeka_Application->run()
#10 {main}

A couple little things.

First, the class name should be ExportEacCpfPlugin.
Then, the context filter in filterActionContexts should add just 'eaccpf', not an array:

$contexts['show'][] = 'eaccpf'; 

If those are all being registered as expected, the last thing is just the show.eaccpf.php file in the plugin’s views/shared/items folder.

I made these modifications and now, when I append ?output=eaccpf to URL, the window for open/save the XML file is showing up. I suppose it’s good news.
Thank you.

When I download the XML file, his content is:

 <br />
 <b>Fatal error</b>:  Call to undefined method ExportEacCpfPlugin::exportItem() in <b>/var/www/html/v1/plugins/ExportEacCpf/views/shared/items/show.eaccpf.php</b> on line <b>16</b><br />

I know I have to create a view in order to construct my XML output (step 4).
The content of show.eaccpf.php is :

<?php
$item = get_current_record('item');
$itemID = $item->id;
$exporter = new ExportEacCpfPlugin();
if(!isset($itemID))
  die('ERROR: item ID not set');
header('Content-Type: application/xml');
header('Content-Disposition: attachment; filename="Item_'.$itemID.'.xml"');
try{
  echo $exporter->exportItem($itemID);
} catch (Exception $e) {
  $this->flashMessenger->addMessage($e->getMessage(),'error');;
}
?>

Is that the right model to start?

Well, the error comes from ExportEacCpfPlugin::exportItem() not being defined. It looks like that’s where you would be generating the XML and echoing it back out. I often find it easier to just build the XML in the view itself, passing in whatever variables or data you need. That said, I don’t know the details of EacCpf, so there might be things I’m not aware of that make it make more sense to build it in the plugin function, but that’s usually the exception to the rule.

It works, thank you!
Now I’m working on the output.

One more question about the output.
In ExportEacCpfPlugin.php I’m recalling each Dublin Core fields without any problems with instruction like this:

$agent = $item->getElementTexts('Dublin Core', 'Creator')[0];

How can I recall elements from a new element type I’ve created or from Person Item Type Metadata?

This solution doesn’t seem correct
$birthdate = $item->getElementTexts('Person', 'Birth Date')[0];

It sounds like instead of Person, use Item Type Metadata. You can always see the list of Element Sets on the Admin->Settings->Element Sets page. Use the name of the Element Set that’s given there.

That’s right, now it works perfectly.
Is there a way I can define this output format is enable just for a particular collection or element type and not for all the items ?
Actually it would be useless and a bit strange to propose this output for example for bibliographical items.

Good question! Coincidentally, I’ve been digging into it lately for one of my projects. :slight_smile:

I think the best way at it is to look at the controller key that’s passed in with the $args to the action_contexts filter. It will depend on the details of what you’re doing, but that should give you a path to the info you need.

This simplified example only adds a VRA output context to Items, but does not add it for item id 3780. For a real check, you’d probably dig up the actual item from the database and make whatever checks are needed.

    public function filterActionContexts($contexts, $args)
    {
        $controller = $args['controller'];
        $params = $controller->getAllParams();
        if($params['controller'] == 'items') {
            if (isset($params['id']) && $params['id'] != 3780) {
                $contexts['show'][] = 'vra';
            }
        }
        return $contexts;
    }

Thank you Patrick. I’ve followed the same path in order to exclude bibliographical collection.
It works!

public function filterActionContexts($contexts, $args){
    $controller = $args['controller'];
    $params = $controller->getAllParams();
    if($params['controller'] == 'items') {
        $item = get_record_by_id("item",$params['id']);
        if(!is_null($item)) {
            $collection = get_record_by_id("collection", $item['collection_id']);
            $collectionName = metadata($collection, array('Dublin Core', 'Title'));
            if($collectionName != 'Bibliography'){
                $contexts['show'][] = 'eaccpf';
            }
        }
    }
    return $contexts;
}

Hi,

if someone is interested on this XML output format, I’ve recently released a plugin: https://github.com/sgraziella/ExportEacCpf

The output EAC-CPF is available for authority files on this under construction website: http://josticeetplet.huma-num.fr , for ex. here http://josticeetplet.huma-num.fr/items/show/2 (“Formats de sortie” > “eaccpf”).

All suggestions are welcome!