6

Right now, we have a matrix field called post body which has all our content, we have text, image, video etc... In our image block we have 2 fields, An asset field called image & a plain text field called caption.

When I first set this site up, admittedly I didn't plan it properly at all and now we allow several images to be uploaded in the single field but we want to be able to set individual captions for each of the images.

Not sure if this is the right way to phrase the question, how would I go about moving the contents of postbody.block.caption to postbody.block.image.caption for every image in that field?

This is going to be a once off migration of content so I'm not sure if it warrants a plugin, would I be able to do this with a quick & dirty sql/yii query?

Here is what I have so far

<?php

$craft = require '../craft/app/bootstrap.php';

$criteria = $craft->elements->getCriteria(Craft\ElementType::MatrixBlock);
$criteria->fieldId = $craft->fields->getFieldByHandle('postBody')->id;
$criteria->type = "image";
$criteria->limit = null;
$blocks = $criteria->find();

foreach ($blocks as $block) {
    if ($block->caption) {
        foreach($block->image as $image) {
            $block->image->imageCaption = $block->caption;
        }
        $block->caption = NULL;
        $craft->matrix->saveBlock($block);
    }
}
?>

But that gives Property "Craft\MatrixBlockModel.caption" is not defined.

Edit I’m now at the stage where the contents of the caption field has been saved to each of the images in that block, but i cant seem to set the caption field on the block to null. Here is what I have at this stage

 $craft = require '../craft/app/bootstrap.php';

$criteria = $craft->elements->getCriteria(Craft\ElementType::MatrixBlock);
$criteria->fieldId = $craft->fields->getFieldByHandle('postBody')->id;
$criteria->type = "image";
$criteria->limit = null;
$blocks = $criteria->find();

foreach ($blocks as $block) {
    if ($block->caption) {

        $caption = "<p>".$block->getContent()->caption."</p>";
        foreach($block->image as $image) {
            $asset = $craft->elements->getElementById($image->id);
            if(empty($asset->getContent()->imageCaption)) {
                $asset->getContent()->imageCaption = $caption;
                $success = $craft->assets->storeFile($asset);
            }
        }

        $block->setContent(array(
            'caption' => '',
        ));

        $success = $craft->matrix->saveBlock($block);

        dd($success);

    }
}
4

I've managed to achieve something which works in the least technical way I can think of. Other solutions might involve migrating data directly within the database, but I figure this is a good starting point.

Let me know how you get on.

  1. Create an RSS feed, ensuring that the data you want to move is populating the feed.

Here's a RSS template from the CraftCMS documentation...

  1. Grab the FeedMe plugin...

Within FeedMe, the Entry Title is required for it to work, so, if the Entry Title is what you need to move to another field, you will need to make sure it appears more than once within a RSS-item e.g.

        {% for entry in craft.entries.section('location').find() %}
        <item>
            <title>{{ entry.title }}</title>
            <link>{{ entry.title }}</link>
            ...
        </item>
        {% endfor %}

In my test example, I have a Channel called 'Locations' - the Title field contains names of Cities.

I want to migrate these Titles, to a new custom field called 'City name'.

  1. Within FeedMe, create a new Feed, choosing the destination Section and Content Type. Hit the 'Save & Continue' button.

  2. The last screen of FeedMe allows you to 'field match' (assign) the different RSS tag content, to a specific field e.g. 'Link' -> 'City name'. See image below...

enter image description here

In my test, I migrated field contents between two fields within the SAME Section and Content-Type.

Thoughts welcome.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.