Jump to content

Automate Repeater Matrix types creation with RockMigrations


Ivan Gretsky
 Share

Recommended Posts

I don't know the current state and if you ask me, wait a little for the launch of RockPageBuilder 😄 

But besides that it should really not be a problem to bring support for RepeaterMatrix to the new version of RockMigrations. It should just be pulling the methods from RockMigrations1 into the new module. If you search for "matrix" in https://github.com/baumrock/RockMigrations1/blob/main/RockMigrations1.module.php you'll see all the necessary methods.

@gebeer what's your progress on this? 🙂 

  • Like 1
Link to comment
Share on other sites

15 hours ago, Ivan Gretsky said:

Good day, @bernhard, @gebeer and everyone!

There was a question about Repeater Matrix support in the old main topic. And @gebeer wrote he had some code that could handle it and he was going to share it with a PR. What is the state of this feature, friends?

 

Hi, my current state of RepeaterMatrix (RM) integration is here: https://github.com/gebeer/RockMigrations/tree/repeatermatrix It is based off @bernhard's dev branch. I just merged the latest changes from dev into my repeatermatrix branch. I have basically done what Bernhard suggested and ported over the original RM methods from RockMigrations v1 and did some minor adjustments.

You can create RM fields inside the $rm->migrate(['fields]) array like this:

                self::content_blocks => [
                  'label' => 'Content Blocks',
                  'type' => 'FieldtypeRepeaterMatrix',
                  'repeaterTitle' => '#n: {title}',
                  'familyFriendly' => 1,
                  'repeaterDepth' => 0,
                  'tags' => 'repeatermatrix',
                  'repeaterAddLabel' => 'Add New Block',
                  'columnWidth' => 100,
                ],

Note that I'm using class constants in my Site module for field names. You can of course use ordinary strings here.
Alternatively you can create the field like this:

		$rmfContent = $rm->createField('content_blocks', 'FieldtypeRepeaterMatrix', ['label' => 'Content Blocks', 'tags' => 'content']);

And then after the $rm->migrate() method you can define your RM types like this:

                $rm->setMatrixItems(self::content_blocks, [
                    'test_rte' => [
                        'label' => 'Test Repeater',
                        'fields' => [
                            self::title => [
                                'label' => 'Title',
                                'required' => 0,
                            ],
                            self::images => [
                                'label' => 'My Images',
                            ],
                            self::rte => [
                                'label' => 'My Text',
                            ],
                            'my_repeater' => [
                                'label' => 'Test RTE in RepeaterMatrix',
                            ],
                        ]
                    ],
                ]);

As you can see, you can also have regular repeater fields inside RM types.

Besides setMatrixItems() there are following RM related methods:
setMatrixItem(), setMatrixItemData(), addMatrixItem(), removeMatrixItem()

There is no way atm to have the full field definition inside the $rm->migrate() method as array definition. That is something that would need some extra work mainly because the getCode() method as is doesn't play nicely with RM fields.

But other that that it seems to work pretty well. Actually I'm using it in a bigger project which is still in development and makes heavy use of RM fields with nested repeaters.

I would be happy if you and others could test this. @gornycreative wanted to have a play with it some weeks ago. Don't know if he already had the time to look at it.

14 hours ago, bernhard said:

I don't know the current state and if you ask me, wait a little for the launch of RockPageBuilder 😄 

Eagerly looking forward 🙂 It is totally different from RepeaterMatrix but really great what I saw so far.

  • Like 4
Link to comment
Share on other sites

I will be using this hopefully going forward instead of the typical import/export process for my baseline profile, which takes into account workflows that are more familiar to desktop publishers and allows for traditional task delegation - photo, content, layout, section editors, etc.

If there is interest in this, I will provide at least the basic core structure and page classes - might be a good advanced example of how things can be done for publishing projects.

I don't have an exact ETA, I'm still working on AdminStyleChroma which is my admin theme color manager and I'm also working on a Color Thief image field implementation - both of which will have official threads and releases and when they are ready.

  • Like 1
Link to comment
Share on other sites

  • 5 months later...
On 4/25/2023 at 10:23 AM, gebeer said:

For all that are interested in testing, I have created a PHP7.4 compatible version at https://github.com/gebeer/RockMigrations/tree/repeatermatrix-php74

It just so happens that I needed it urgently on a live project where I couldn't change the PHP version in time 🙂

Good day, @gebeer!

I would be really happy to see those RM methods merged into RockMigrations core. I am testing things right now.

This is what I've found so far.

  1. There are some not-deleted bd()'s.
  2. I am trying to create RM field and add types in one run (see the code below)  But it seems not possible. Should I put some code in between to make it work?
    <?php
    
    namespace ProcessWire;
    
    /** @var RockMigrations $rm */
    $rm = $modules->get('RockMigrations');
    
    $rm->installModule(
      "FieldtypeRepeaterMatrix"
    );
    
    $rmfContent = $rm->createField('content_blocks', 'FieldtypeRepeaterMatrix', ['label' => 'Content Blocks', 'tags' => 'content']);
    
    $rm->setMatrixItems('content_blocks', [
      'test_rte' => [
          'label' => 'Test Repeater',
          'fields' => [
              'title' => [
                  'label' => 'Title',
                  'required' => 0,
              ],
              'images' => [
                  'label' => 'My Images',
              ],
              'rte' => [
                  'label' => 'My Text',
              ],
              'my_repeater' => [
                  'label' => 'Test RTE in RepeaterMatrix',
              ],
          ]
      ],
    ]);

     

Link to comment
Share on other sites

On 4/24/2023 at 3:41 PM, gebeer said:

Sure. I'd like some other people test this before I make the PR.

Good day, @gebeer!

I've tested setMatrixItems() metod - it seems to work fine so far. There are some bd()'s that cause errors when the field to be added does not exist. But that is minor thing. I am eager to see this PR merged. Ready to do more testing if needed. But just maybe it is better to do it with your code already in the core? We do not want to lose this work!

Link to comment
Share on other sites

9 hours ago, Ivan Gretsky said:

Good day, @gebeer!

I've tested setMatrixItems() metod - it seems to work fine so far. There are some bd()'s that cause errors when the field to be added does not exist. But that is minor thing. I am eager to see this PR merged. Ready to do more testing if needed. But just maybe it is better to do it with your code already in the core? We do not want to lose this work!

Hi Ivan, thanks a lot for testing this. I've been working with it on a bigger project for the last 9 months and it seems quite stable. I had some health issues and am getting slowly back on track. Will do the PR on the weekend.

  • Thanks 1
Link to comment
Share on other sites

On 9/28/2023 at 12:53 AM, Ivan Gretsky said:

I am trying to create RM field and add types in one run (see the code below)  But it seems not possible. Should I put some code in between to make it work?

Unfortunately it is not possible to create a RM field in one go. The way I do it:
 

		// first create the field
		/** @var RepeaterMatrixField $rmfProduct */
		$rmfProduct = $rm->createField('content_product', 'FieldtypeRepeaterMatrix', [
			'label' => 'Product Content Blocks',
			'tags' => 'products',
			'repeaterAddLabel' => 'Add New Block',
		]);
		
		// then populate it
		if (wireInstanceOf($rmfProduct, 'RepeaterMatrixField')) { // TODO quickfix find out why $rmf instanceof Field after create
			$test = $rm->setMatrixItems('content_product', [
				'features' => [
					'label' => 'Features',
					'fields' => [
						'repeater_product_features' => [],
					]
				],
				'gallery' => [
					'label' => 'Image Gallery',
					'fields' => [
						'images' => [],
					]
				],
				...
			]

I will add a hint to the docstring.

Note the issue that I had, that after first creation of the field it returned an instance of Field, not RepeaterMatrixField. So I added some logic to avoid errors. Then needed to run initial migration twice to populate. Haven't found out why that happened, yet.

  • Like 1
Link to comment
Share on other sites

2 hours ago, gebeer said:

Hi Ivan, thanks a lot for testing this. I've been working with it on a bigger project for the last 9 months and it seems quite stable. I had some health issues and am getting slowly back on track. Will do the PR on the weekend.

Thanks @gebeer! I really wish you a quick recovery.

Great to hear the code is not abandoned and the PR is coming!

Link to comment
Share on other sites

48 minutes ago, Spinbox said:

Say what, more Rock? Any update to this?

Yes 😎 The module is done and ready for production. Just the infrastructure to sell it is not, as we unfortunately have no dedicated place to sell commercial 3rd party modules in the PW ecosystem 😞 If you are interested just send me a PM and you'll get a horrible and outdated preview video 😄 

Link to comment
Share on other sites

On 9/29/2023 at 6:34 AM, gebeer said:

Hi Ivan, thanks a lot for testing this. I've been working with it on a bigger project for the last 9 months and it seems quite stable. I had some health issues and am getting slowly back on track. Will do the PR on the weekend.

@gebeer, did you manage to make that PR? Not pushing but just trying not to miss this thing I am looking forward to use)

Link to comment
Share on other sites

  • 2 weeks later...
Hello!
 
I still have a problem related to creation of repeater matrix types. There is a function:
 
public function createRepeaterMatrixField(string $name, array $options, bool $wipe = false)
  {
    $items = array_key_exists('matrixItems', $options) ? $options['matrixItems'] : null;
    if ($items) unset($options['matrixItems']);
    // var_dump($items);
    // create field
    $field = $this->createField($name, 'FieldtypeRepeaterMatrix', $options);
    // populate matrix items
    if ($field && wireInstanceOf($field, 'RepeaterMatrixField')) {
      $this->setMatrixItems($field, $items, $wipe);
    }

    return $field;
  }
 
$field variable is supposed to be RepeaterMatrixField, but it's only a Field. What I'm doing wrong? I use the code from the documentation from https://github.com/baumrock/RockMigrations/tree/dev#repeatermatrix-field. Can you please tell me why it's Field and not RepeaterMatrixField?
 
Edit 1: I think it's field because $this->createField returns Field but not RepeaterMatrixField.
 
Edit 2: If I use setMatrixItems, then items are being added in the second run.
 
  • Confused 1
Link to comment
Share on other sites

17 hours ago, Clarity said:

Edit 1: I think it's field because $this->createField returns Field but not RepeaterMatrixField.

Latest dev branch: https://github.com/baumrock/RockMigrations/blob/da0b08b9cc65ee5573a5041971fe6ec575130b98/RockMigrations.module.php#L4107

In the phpdoc the return value is RepeaterMatrixField|null. But inside the function when the field is created with $this->createField($name, 'FieldtypeRepeaterMatrix', $options); it seems to return the generic class Field.

I also sometimes experienced the problem, that you described. As a workaround, I first created the field and then added the items in a second run inside a conditional which tests for the correct class of the created field from the first run.

But in my latest tests, this did not occur. Unfortunately I can't seem to find out why this is happening sometimes.

  • Like 1
  • Confused 1
Link to comment
Share on other sites

  • 1 month later...

Thanks for the update @gebeer. I'm currently upgrading my migration code from the old version of RockMigrations to the new one. However, I am running into the issue where creating the field (using createRepeaterMatrixField()) returns a Field instance and not RepeaterMatrixField. In my case I can get the code to return the right instance after saving the repeater matrix through the ProcessWire admin webpage. Maybe something is missing in RockMigration's createField()when creating a Repeater Matrix?

One other thing is that we have ProFields Repeater Matrix version 0.0.8 and not the latest (0.1.1). We are in the process of purchasing a renewal. I'm hoping that once we use the latest version, the migration code will work.

 

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...