Jump to content

[SOLVED] RockMigration files/directory structure


nurkka
 Share

Recommended Posts

I am still trying to wrap my head around RockMigrations. With my first attempts, my migrate.php grew to several hundred lines, so I wanted to structure the migrations. I also read that @bernhard always uses a module Site.module.php, which I also created in my project. I also wanted to split my migrations into several files, so I did the following:

Directory structure:

- modules
    - Site
        - migrations 
            - fields
                fieldset_visible_responsive.php
                fieldset_visible_language.php
        Site.module.php

Site.module.php

<?php namespace ProcessWire;

class Site extends WireData implements Module {

	public static function getModuleInfo() {
		return [
			'title'    => 'Site',
			'singular' => true,
			'autoload' => true,
		];
	}

	public function init() {
		$rm = $this->wire->modules->get('RockMigrations');
		if ($rm) {
			$rm->watch($this);
			$rm->watch( __DIR__ . '/migrations/fields/fieldset_visible_responsive.php' );
		}
	}

	public function migrate() {
		$this->migrate_fields();
	}

	public function migrate_fields () {
		include __DIR__ . '/migrations/fields/fieldset_visible_responsive.php';
	}

}

fieldset_visible_responsive.php

<?php namespace ProcessWire;

$rm = rockmigrations();

$rm->createField('checkbox_visible_responsive_mobile', 'FieldtypeCheckbox', [
	'columnWidth'     => 33,
	'label'           => 'Mobile',
]);

[...]

Now, I have some questions:

- Is there a RockMigrations feature to combine the "watch" command with an "include"? As the watch commands apparently have to be placed in init() and the migrations in migrate(), the migration files to be included have to be referenced in both places. Okay, I could write a config array or something for this, but is there a _native_ RockMigrations feature or best practice for that?

- I guess you also do not put all your migrations into Site.module.php – What is your strategy for staying on top of things? Assuming one has lots and lots of "global" fields, which are not related to specific templates, for what you would perhaps use custom page classes.

- Is the .php suffix mandatory for the Site-module, or can it also be named Site.module, like other ProcessWire modules?

@bernhard And thanks again for the module! I think it's fantastic that you have donated such an impressive module to the community. Even as I am not 100% grasping all the possibilities and features of RockMigrations yet, I think the possibility to create and modify fields by configuration could (and should) also become part of the core. I think other CMS/CMF are already doing that.

Link to comment
Share on other sites

Hey @nurkka thx for your interesting questions!

4 minutes ago, nurkka said:

- Is there a RockMigrations feature to combine the "watch" command with an "include"? As the watch commands apparently have to be placed in init() and the migrations in migrate(), the migration files to be included have to be referenced in both places. Okay, I could write a config array or something for this, but is there a _native_ RockMigrations feature or best practice for that?

You should be able to add Site.migrate.php which should automatically be watched and migrated on change. Though I'm not using this any more, so if anything doesn't work let me know.

4 minutes ago, nurkka said:

- I guess you also do not put all your migrations into Site.module.php – What is your strategy for staying on top of things? Assuming one has lots and lots of "global" fields, which are not related to specific templates, for what you would perhaps use custom page classes.

I put all global migrations for my project into Site.module.php, that's it. All others go either into custom page classes or - that might make a difference - into RockPageBuilder blocks. So many of my fields that I need are related to RockPageBuilder blocks and therefore I don't get a bloated Site.module.php; But I don't think it's bad to have a larger Site.module.php;

7 minutes ago, nurkka said:

- Is the .php suffix mandatory for the Site-module, or can it also be named Site.module, like other ProcessWire modules?

Nothing special here. Everything that PW understands will work. I'm using .php because my IDE does not understand .module for code highlighting and suggestions. I guess I could configure that, but I prefer to have .php since that will work not only for me but also for everybody else using the module.

8 minutes ago, nurkka said:

@bernhard And thanks again for the module! I think it's fantastic that you have donated such an impressive module to the community. Even as I am not 100% grasping all the possibilities and features of RockMigrations yet, I think the possibility to create and modify fields by configuration could (and should) also become part of the core. I think other CMS/CMF are already doing that.

Thx! I thought it could be a game changer for PW. Apparently it wasn't, but it was at least for me and for some others ? I think Ryan didn't even try the module unfortunately and he recently mentioned that migrations are not on his list, as he doesn't work that way. But I think as we have RockMigrations things could be worse ^^

Link to comment
Share on other sites

@bernhard Thanks for your reply and valuable info! I wanted to try RockPageBuilder for some time, but I am still working on legacy projects. I will make a completely new website in september, so that will be my opportunity to finally use it.

As for the case described above, where I want to have different migration files for different fields, templates, etc, I found a solution. It is possbile to tell RockMigrations to watch a whole folder and also to watch it recursively, by using rockmigrations()->watch( 'DIRECTORYNAME', true, [ 'recursive' => true ] );

So this works now:

<?php namespace ProcessWire;

class Site extends WireData implements Module {

	public static function getModuleInfo() {
		return [
			'title'    => 'Site',
			'singular' => true,
			'autoload' => true,
		];
	}

	public function init() {
		$rm = $this->wire->modules->get('RockMigrations');
		if ($rm) {
			// $rm->watch($this); // not needed b/c we have no migrations directly in this module class file
			$rm->watch( __DIR__ . '/migrations', true, [ 'recursive' => true ] );
		}
	}

	// not needed anymore b/c of $rm->watch in init()
	/*
	public function migrate() {
		$this->migrate_fields();
	}
	public function migrate_fields () {
		include __DIR__ . '/migrations/fields/fieldset_visible_responsive.php';
		include __DIR__ . '/migrations/fields/fieldset_visible_language.php';
	}
	*/

}

This way, I can have a lean Site.module.php and move all migrations to dedicated files.

  • Like 1
Link to comment
Share on other sites

  • nurkka changed the title to [SOLVED] RockMigration files/directory structure

Nice! This sounds like a cool setup! Totally forgot about the recursive watch feature ? 

Would be interested to see the final structure. Do you have one file per field and template etc? The pro of this setup is that if you had 100 files and you changed one of them RM will only migrate that single file, which will make the reload very fast as it has only very little to do. The con could be that sometimes the order of migration matters, so with separate files you don't have control over that. You can define a watch priority (similar to hook priority), but then you'd need to list every single file, which is also tedious.

Let me know what you find out and how it goes!

Link to comment
Share on other sites

In this case, the setup is for a legacy project, and I am still experimenting, which is the best setup for me. In this project, I have lots and lots of RepeaterMatrix items, with nested Repeaters, Fieldset Pages, Combo fields and of course a lot of "simple" fields, like text_1 to text_20 etc. I will not be able to refactor everything into migrations, because that would be too much work. But for new fields, I wanted to use RockMigrations. RockMigrations only adds things and does not remove anything, until you tell it to, so it is perfect for this use case.

Thanks for pointing out, that the migrations must be executed in the right order. I hope that this won't be a problem in my case, although I don't know for sure yet. Having all migrations in migrate.php or in Site.module.php would stress me out, because I would have hundreds of lines of code in one file. Currently, I am only adding new fields, and I am grouping the migrations accordingly. E.g. when adding a fieldset page, I wrote a migration file with all its dependent fields and the fieldset page at the end. When adding a RepeaterMatrix item, I would define all the dependent fields and the RepeaterMatrix item migration in one file. So I would always try to group migrations which are connected/dependent into one file. Of course, this is not perfect, because I also use "global" fields like "text_1" in my RepeaterMatrix items. In a new project, I would probably simply add a new text field for every RepeaterMatrix item, if needed.

I am sure, one could also write a custom page class for a RepeaterMatrix item, and add the migrations there, but I have to learn this yet. Perhaps it's also better not to mix several ways to integrate migrations, because of the maintainability of the site. Anyway, I am really happy with the new setup for now ? 

Link to comment
Share on other sites

12 hours ago, nurkka said:

Anyway, I am really happy with the new setup for now ?

Great! You can also add one file _globals.php or something that would be called at first and there you could place things that need to be done first, eg creating some fields where order matters:

<?php

// _globals.php
$rm = rockmigrations();
$rm->createField('field_z');
$rm->createField('field_a');

// field_a.php
$rm->setFieldData('field_a', [
  // something that references field_z
]);

// field_z.php
$rm->setFieldData('field_z', [ ... ]);

Migration order should be

  1. _globals.php
  2. field_a.php
  3. field_z.php

_globals.php should always be loaded first (because of the underscore) and therefore as soon as field_a.php is included field_z already exists and the settings can be correctly applied.

You could also add a file zzz_final.php or something that is done at the very end.

  • Thanks 1
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...