Customizing Item Output

I've just upgraded to Omeka 2.1.2. I was really pleased with my item output in my old version of Omeka, which had a custom.php file in my Berlin theme folder. I tried moving the custom.php file over to the new installation in the same place, but it's not working. I'd be grateful for any suggestions.

Thanks,
Karen

<?php

/**
* Show Item Metadata function that loops through an internal array of labels
* and their associated fields.
*
* @param Item|null $item
* @return string The HTML for the item metadata.
*/
function berlin_custom_item_metadata($item = null)
{
$html = '';

$item = $item ? $item : get_current_item();

// The list of fields we want to display, using 'Label' => item() Put them
// in the order you want them displayed. Add more to the array, separated
// by a comma.
$fields = array(
'Image' => item('Dublin Core', 'Rights', null, $item),
'Primary Source Text' => item('Item Type Metadata', 'Text', null, $item),
'Commentary' => item('Dublin Core', 'Description', null, $item),
'Source' => item('Dublin Core', 'Source', null, $item),
'Date' => item('Dublin Core', 'Date', null, $item),
'Further Reading' => item('Dublin Core', 'Relation', null, $item),
'Contributor' => item('Dublin Core', 'Contributor', null, $item)
);

// Loop through our array of fields, breaking out the label and value.
foreach ($fields as $label => $value) {

// Only display the field if it has a value.
if ($value) {

// Construct the HTML for displaying the label and value.
$html .= '<div class="field field-'. text_to_id($label) .'">'
. '<h2>'.$label.'</h2>'
. '<div class="field-value">'
. $value
. '</div>'
. '</div>';

}

}

return $html;

}

_Almost_ everything here can be done more easily in 2.1. If there is nothing in the elements you don't want, there's a toggle for displaying or not empty elements in Appearance->Settings.

If there's data stored in the admin side, but you don't want displayed publicly, John's Hide Elements plugin lets you configure elements to hide on the public side.

Editing an Element Set under Settings->Element Sets lets you reorder the display of elements.

Some combination of those should get you everything except the mixing of Dublin Core data with Item Type Metadata data. I'm not entirely sure how to build that back in off the top of my head. But, it is a good use case for us to keep in mind is out there.

Thanks so much Patrick. I just took a look and it does look a lot easier than 1.5.

I'm fiddling around, and don't see a way to rename the element headers on the dashboard, just a way to comment. Is that right?

Thanks for your help and patience with this upgrade!
Karen

Ah. Yes, I missed that. That's also not there.

I think that one way (not sure if it's the best way) to get to the same effect would be to override application/views/common/record-metadata.phpin your theme.

What comes in as $elementsForDisplay is a big array of elements for the record, nested by element set ("Dublin Core", "Item Type Metadata"), and then by the element name. As it stands, it loops through DC elements, then other element sets.

NB. Without additional checking, this would also affect the display for Collections

Instead of looping through everything, you might be able to attack it by directly plucking out the metadata field you want from the array and building the html around it. The element info for Dublin Core Title would -- I'm _pretty_ sure -- look like:

<?php $titleElementInfo = $elementsToDisplay['Dublin Core']['Title']; ?>
<?php foreach ($titleElementInfo['texts'] as $text): ?>
   <div class="element-text"><?php echo $text; ?></div>
<?php endforeach; ?>

That's a fair amount of hard coding once you go through all the elements you want, but not too much more than what's in your function.

I suppose you could also consolidate things by picking out the data you want, in the order you want, at the top of the script, and then do a loop. That would still leave a check somewhere to rename the elements, though.

Thanks so much Patrick. I'm happy to code each DC element individually to have them retitled and displayed the way I want. I need to know the path to the file I need to change in 2.0 to make these items display the way I want. On my wish list are:

1) A Fullsize image file at the top of the page rather than files at the bottom.
2) Rename DC files and intermingle them with the Item Type Metadata, in the order I want.
3) Draw that blue box that was once there around the Description DC to highlight it.

Is there a way to do this in one file as I did before? Or, if not, could you direct me to the right file? I get what you are saying conceptually above, but my php isn't good enough to dive in. Thanks!!

Oh, I should add, I also don't want the titles "Dublin Core Fields" and "Item Type Metadata" to show up at all!

To get those three things in, it'll probably require changing two files, but shouldn't be too tricky.

First, you'll want to create a new file called record-metadata.php in the berlin/common folder. This will override what's in /application/views/scripts/common/record-metadata.php, the file that spits out all the metadata fields.

What we'll do is first, check if we are on an item show page. If so, we'll redo HTML to the way we want. Otherwise, we'll just copy over what's in the original record-metadata.php file so that it doesn't break the collection show page.

Here's a start to it, with a couple comments.

<?php if(isset(get_view()->item)): //check if this looks like an item show page ?>

<?php
//dig through the elements for display that are passed into this file
//put it all into a new array of just the elements we want
//this should let you collect the elements you want in the order you want
//follow this pattern to get more or change the order

$wantedElements = array();
$wantedElements['Title'] = $elementsForDisplay['Dublin Core']['Title'];
if(isset($elementsForDisplay['Item Type Metadata'])) {
    $wantedElements['Primary Source Text'] = $elementsForDisplay['Item Type Metadata']['Text'];
}
$wantedElements['Commentary'] = $elementsForDisplay['Dublin Core']['Description'];
?>

<div class="element-set">
    <?php foreach ($wantedElements as $elementName => $elementInfo): ?>
    <div id="<?php echo text_to_id(html_escape("$elementName")); ?>" class="element">
        <h3><?php echo html_escape(__($elementName)); ?></h3>
        <?php foreach ($elementInfo['texts'] as $text): ?>
            <div class="element-text"><?php echo $text; ?></div>
        <?php endforeach; ?>
    </div><!-- end element -->
    <?php endforeach; ?>
</div><!-- end element-set -->

<?php else: ?>

<?php foreach ($elementsForDisplay as $setName => $setElements): ?>
<div class="element-set">
    <h2><?php echo html_escape(__($setName)); ?></h2>
    <?php foreach ($setElements as $elementName => $elementInfo): ?>
    <div id="<?php echo text_to_id(html_escape("$setName $elementName")); ?>" class="element">
        <h3><?php echo html_escape(__($elementName)); ?></h3>
        <?php foreach ($elementInfo['texts'] as $text): ?>
            <div class="element-text"><?php echo $text; ?></div>
        <?php endforeach; ?>
    </div><!-- end element -->
    <?php endforeach; ?>
</div><!-- end element-set -->
<?php endforeach; ?>

<?php endif; ?>

That'll get the reordering, and clobber the "Dublin Core Fields" thing.

For the blue box, you'll just need to tweak the css. That's probably most easily done in the berlin/items/show.php file.

Right at the top, before the call to head(), you can stuff in some new CSS like this. You'll need adjust the actual CSS, of course, but here's the basic approach.

$css = "#commentary {border: 2px solid blue;}";
queue_css_string($css);

Last, moving the files to the top is pretty easy. You'll see in the items/show.php file the chunks of code that produce the metadata and the files. Just switch those around. I'm not sure if it does the fullsize by default or not, though.

Thanks so much Patrick! I have to teach, but will take a deep breath and try this later this afternoon!

Actually, just looking through this quickly, I see a rerouting happening but I'm not sure I see what part of the code I would use to rename my DC elements. Would you be able to give me an example of changing one (Related Resources to Further Reading) that I could use as a template to change the others?

The $wantedElements array uses the key as the name to display when it digs up the data from the bigger $elementsForDisplay array. So

$wantedElements['Commentary'] = $elementsForDisplay['Dublin Core']['Description'];

takes the DC Description data, and associates it with the label 'Commentary'

Then, in the loop:

<?php foreach ($wantedElements as $elementName => $elementInfo): ?>

the $elementName is what gets displayed, so 'Commentary' get the heading in this line a little below it:

<h3><?php echo html_escape(__($elementName)); ?></h3>

Ah, that's amazing! Thank you so much--can't wait to try this out.

Dear Patrick,

Thanks so much. This seems to be just about doing it but for some reason, the only DC files that now show up are Title and Description. Weirdly, description shows up as "Commentary" which it was named in an old iteration of the site, but right now I have it renamed "Introduction".

In addition to the DC files, I'd like for some of the Item Type Metadata to show up.

I have disabled the hide DC fields plugin, but that didn't change much. I looked for an errant custom.php file that could be causing the problem, but didn't find one.

Any ideas? Thanks again for all your help!
Karen

My guess is that there's just more to build in the $wantedElements array. The example above shows how Dublin Core Description turned into Commentary. You might just need to add in similar lines that build up more of the array.

Could you post up all of the section where that array is being built?

My apologies, I commented too quickly. I'm now seeing that the label commentary is built into the code. I had been confused because I used that term before myself. I'm going to try now using this in conjunction with the plug-in and see if I can get all the wanted labels to appear.

Thanks Patrick, I think you are absolutely right. I will try that right now. I'm sorry I got so confused.

It is now working almost perfectly (!!) except the text from the Item Type Metadata isn't showing up. These are the relevant lines of code:

$wantedElements = array();
$wantedElements['Image'] = $elementsForDisplay['Dublin Core']['Rights'];
$wantedElements['Introduction'] = $elementsForDisplay['Dublin Core']['Description'];
if(isset($elementsForDisplay['Item Type Metadata'])) {
    $wantedElements['Primary Source Text'] = $elementsForDisplay['Item Type Metadata']['Text'];
}
$wantedElements['Source'] = $elementsForDisplay['Dublin Core']['Source'];
$wantedElements['Date'] = $elementsForDisplay['Dublin Core']['Date'];
$wantedElements['Further Reading'] = $elementsForDisplay['Dublin Core']['Relation'];
$wantedElements['Contributor'] = $elementsForDisplay['Dublin Core']['Contributor'];
?>

Maybe that if statement doesn't need to be there?

I took out the if bit and now the title "Primary Source Text" does show up, but not the text from the field itself. Am a little stumped on this one.

First guess is that in the current version of the things, the metadata field you are using isn't called "Text"? Did it change to something else? (The terms I used in the code are from your original function, but it sounds like some things have changed since then?)

Scratch that. My bad!

Instead of 'Item Type Metadata', it wants the name of the item type before it. So I'd guess what you'd want is:

$wantedElements['Primary Source Text'] = $elementsForDisplay['Document Item Type Metadata']['Text'];

Thanks so much again Patrick for all the help. I'm 90% of the way there, but still having trouble with styling my Item Type Metadata 'Text" Field (renamed 'Primary Source Text'). I tried stuffing the code above in, but may have put it in the wrong place. Then I tried the solution from the earlier version of my site in Omeka 1.5. (http://omeka.org/forums/topic/re-naming-dc-fields). I added this code to record-metadata.php:

' // Loop through our array of fields, breaking out the label and value.
foreach ($fields as $label => $value) {

// Only display the field if it has a value.
if ($value) {

// Construct the HTML for displaying the label and value.
$html .= '<div class="field field-'. text_to_id($label) .'">'
. '<h2>'.$label.'</h2>'
. '<div class="field-value">'
. $value
. '</div>'
. '</div>';

}

}

return $html;

}'

and the styling I want to my CSS:

'.field-primary-source-text {
background-color:#EEEEEE;
background-position:initial initial;
background-repeat:initial initial;
margin-bottom:1.5em;
overflow:hidden;
padding:1.5em 20px;
}'

But no luck! Any suggestions would be greatly appreciated.

Hi Patrick,

My apologies, ignore that last post, I figured out I was altering the wrong file. I'm now working with the berlin/items/show.php file, but am still not quite there. I tried stuffing the CSS at the very top, but it just prints it out at the top of the page. I must be missing something basic. Here's what I did:

$css = "#primary-source-text {
  background-color:#EEEEEE;
  background-position:initial initial;
  background-repeat:initial initial;
  margin-bottom:1.5em;
  overflow:hidden;
  padding:1.5em 20px}";
queue_css_string($css);

I'm also looking for full size images on my show items page. The code defaults to thumbnails:

`<div id="item-images">
<?php echo files_for_item(); ?>
</div>`

Can you tell me how I would switch to full size?

thank you so much!

Hi Patrick,

I'm sorry I posted so many times! I now have the box figured out, using your answer from this post: http://omeka.org/forums/topic/adding-a-colored-box-around-one-metadata-item#post-82269

Now I just need to know how to switch to a full sized image, if possible.

Thanks!
Karen