Jump to content

Modules that create and manage it's own set of fields and templates


Jonathan Lahijani
 Share

Recommended Posts

One huge strength of ProcessWire is the ability to create fields and templates on the fly in the admin and the beautiful architecture of it all.  WordPress on the other hand does it the 'postmeta' way which is more loose, but flexible in that fields don't have to be 'registered' and custom templates are purely handled through the existence of a PHP file.  Many pros and cons to each approach, but for modules, the WordPress way allows module developers to not have to worry about field settings and such since the configuration of it is NOT stored in the database. (the new Mystique module is similar to the postmeta approach, very cool)

ProcessWire's approach gets a little complicated in situations where a custom module relies on a set of fields (native fieldtypes) and/or templates.  The MarkupSEO module does this... upon installation, it creates a set of regular ProcessWire fields that the module relies on.

But what happens if a future version of the module requires changes to the settings of a field, needs a new field or needs to delete a field (same for templates)?  At this point we're talking about 'migrations' found in webapp frameworks like Rails, Laravel, etc.  There's the Migrations module, but that's more general purpose.  ProcessWire uses the system updater to update core changes.

Is there a best practice for keeping fields and templates in check for 3rd party modules?  Are there any examples of modules that do this?

  • Like 2
Link to comment
Share on other sites

I agree that this is a challenge. I also find the Mystique approach very interesting!

Did you see my approach of migrations? 

From the docs:

Quote

... and I wanted to be able to use Migrations in my Modules

Migrations are shipped with the module in /site/modules/YourModule/RockMigrations/XXX.php

// 0.0.5.php

<?php namespace ProcessWire;
/**
 * Änderungen für neues Feld "Kundenstatus"
 */
$upgrade = function(RockMigrations $rm) {
  $rm->createField('ernum', 'text', [
    "label" => "ER-Nummer",
  ]);
  $rm->addFieldToTemplate('ernum', 'rockprojecteffort', 'cost_gross');
};

$downgrade = function(RockMigrations $rm) {
  $rm->deleteField('ernum');
};

I can then just do:

git pull

$rm = $modules->get('RockMigrations');
$rm->setModule('YourModule');
$rm->up('0.0.5');

It's not at all complete yet, but it works well on several production projects and simplified my workflow a lot! Here an example of a more complex migration (that is IMHO still self expanatory and easy to create and manage):

<?php namespace ProcessWire;
/**
 * tweaks
 */
$upgrade = function(RockMigrations $rm) {
  $rm->setFieldData('invoiceto', ["labelFieldFormat" => "{rockcontact_parent}, {title}, E-Mail = {rockcontact_email}"], 'rockproject');
  $rm->installModule('Prozesse');
  $rm->installModule('ProcessProzesse');
  $rm->installModule('Rechnungsfreigaben');
  $rm->installModule('ProcessRechnungsfreigaben');
  $rm->addPermissionsToRoles(
    ['prozesse','prozesse-rechnungsfreigaben'],
    ['office-management', 'senior']
  );
  $rm->createField('iscurrent', 'checkbox', [
    'label' => 'Ist der aktuellste von mehreren Einträgen',
    'collapsed' => Inputfield::collapsedNo,
  ]);
  $rm->addFieldToTemplate('iscurrent', 'invoiceconfirmation');
  foreach($this->pages->find('template=invoiceconfirmation') as $p) $p->save();
};

$downgrade = function(RockMigrations $rm) {
  $rm->deleteField('iscurrent');
  $rm->uninstallModule('ProcessRechnungsfreigaben');
  $rm->uninstallModule('Rechnungsfreigaben');
  $rm->uninstallModule('ProcessProzesse');
  $rm->uninstallModule('Prozesse');
  $rm->setFieldData('invoiceto', ["labelFieldFormat" => "{rockcontact_parent}, {title}"], 'rockproject');
};

You see that it makes task that are usually tedious via the API very easy. The first line (setFieldData for invoiceto) sets new field settings in template context, for example.

IMHO the way to go are migrations. The mystique approach looks very interesting indeed, but it will not work in all scenarios (eg when you need to manage/edit/install/uninstall modules or templates or roles and permissions. @LostKobrakai had a reason for developing his module and it took me quite long to understand that ? I just didn't like the implementation a lot due to the reasons mentioned in the docs of RockMigrations. Said that I have to admit that RockMigrations is also still a very early stage implementation of would would be necessary in my opinion. I think PW would strongly need a solid API to handle all those migration stuff properly and easily. Something that makes it easy to migrate between different module versions, upgrade modules, downgrade modules, revert changes, check for compatibility before installation and so on. Something that maybe even automatically syncs the module versions with the migration versions (so that your code is always in sync with your DB, otherwise it would be possible that your code requests a field that does not exist in the DB yet). If that worked all we would have to do would be a "git pull" and pw would take care of the rest.

My module is kind of a quick and dirty implementation of that dream, but it works quite well ? 

  • Like 3
  • Thanks 1
Link to comment
Share on other sites

 Share

  • Recently Browsing   0 members

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