Jump to content

[SOLVED] Fields, Templates and Fieldgroups - how do they interact?


Gadgetto
 Share

Recommended Posts

Hello,

I'm just working on the installer for a bigger module which will need many fields + some templates. To make the installer reusable, I decided to provide the installer with a set of arrays which will hold the required resources (fields, templates, pages, permissions and so on).

This is the set of arrays (not yet finished, some data just for testing):
(separate file Resources.php to be included when needed)

<?php namespace ProcessWire;

$installer_fields = array(
    'goodnews' => array(
        'name' => 'gn_test',
        'type' => 'FieldtypeText',
        'label' => 'GoodNews Test Field',
        'description' => 'Test description for the GoodNews Test Field.',
        'maxlength' => 256,
        '_fieldgroup' => 'gn',
        '_template' => 'goodnews-mailing-container',
    ),
);

$installer_templates = array(
    'goodnews-mailing-container' => array(
        'name' => 'goodnews-mailing-container',
        'noChildren' => 0,
    ),
    'goodnews-mailing' => array(
        'name' => 'goodnews-mailing',
        'noChildren' => 1,
    ),
    
);

$installer_pages = array(
    'goodnews' => array(
        'name' => 'goodnews',
        'title' => 'GoodNews',
        'template' => 'admin',
        'parent' => $this->pages->get($this->config->adminRootPageID),
    ),
    'goodnews-mailing-container' => array(
        'name' => 'goodnews-mailing-container',
        'title' => 'GoodNews Mailings',
        'template' => 'goodnews-mailing-container',
        'parent' => $this->pages->get('/'),
    ),
);

$installer_permissions = array(
    'goodnews' => array(
        'name' => 'goodnews',
        'title' => $this->_('View GoodNews Admin Page'),
    ),
    'goodnews-sender' => array(
        'name' => 'goodnews-sender',
        'title' => $this->_('Send GoodNews Mailings'),
    ),
);

As you can see, each set of fields will hold a '_fieldgroup' and '_template' key/value pair.

Currently I try to write the logic to install the templates and add the required fields - grouped by the fieldgroup - to their templates.

This is my '__install' method so far:
(unfinished in some parts)

    public function ___install() {

        require __DIR__ . '/install/Resources.php';

        $fields      = $this->wire('fields');
        $templates   = $this->wire('templates');
        $pages       = $this->wire('pages');
        $permissions = $this->wire('permissions');
        $modules     = $this->wire('modules');

        /* ====== Pre installation checks ====== */

        // Check if one of the fields to be installed already exists
        foreach ($installer_fields as $installer_field) {
            
            $f = $fields->get($installer_field['name']);
            if ($f) {
                $out = sprintf($this->_("Installation aborted. The field to be installed already exists! Please be sure that you do not have a field with name '%s' before installing this module."), $installer_field['name']);
                throw new WireException($out);
            }
        }
        
        // Check if one of the templates to be installed already exists
        foreach ($installer_templates as $installer_templates) {

            $t = $templates->get($installer_template['name']);
            if ($t) {
                $out = sprintf($this->_("Installation aborted. The template to be installed already exists! Please be sure that you do not have a template with name '%s' before installing this module."), $installer_template['name']);
                throw new WireException($out);
            }
        }
        
        // Check if one of the pages to be installed already exists
        foreach ($installer_pages as $installer_page) {

            $p = $pages->get('template='.$installer_page['template'].', name='.$installer_page['name']);
            if ($p->id) {
                $out = sprintf($this->_("Installation aborted. The page to be installed already exists! Please be sure that you do not have a page with name '%s' before installing this module."), $installer_page['name']);
                throw new WireException($out);
            }
        }
        
        /* ====== Install fields ====== */
        
        $fieldgroups = array();
        
        foreach ($installer_fields as $installer_field) {
        
            $f = new Field();
            $f->type        = $modules->get($installer_field['type']);
            $f->name        = $installer_field['name'];
            $f->label       = $installer_field['label'];
            $f->description = $installer_field['description'];
            $f->maxlength   = $installer_field['maxlength'];
            $f->save();
            
            // Collect field-name in fieldgroups array if available (for later use to add to templates)
            if (!empty($installer_field['_fieldgroup'])) {
                
                $fieldgroups[$installer_field['_fieldgroup']] += $installer_field['name'];

            }
            
        }
		
 



        /* ====== Install templates ====== */
        
        
        
        


        /* ====== Install pages ====== */
        

        foreach ($installer_pages as $installer_page) {
            
            // Create new page
            $page = new Page();
    		$page->name     = $installer_page['name'];
            $page->template = $installer_page['template'];
            $page->parent   = $installer_page['parent'];
            
            $page->process  = $this; 
            
            $page->title    = $installer_page['title'];
            
            // Save page
            $page->save();
            
            // Tell the user we created this page
            $this->message('Created Page: '.$page->path);
        }


        /* ====== Install permissions ====== */

        foreach ($installer_permissions as $installer_permission) {
            
            // Only install permission if it does not already exist
            $permission = $permissions->get('name='.$installer_permission['name']);
            if (!$permission->id) {
                $p = new Permission();
                $p->name  = $installer_permission['name'];
                $p->title = $installer_permission['title'];
                $p->save();
                
                // Tell the user we created this permission
                $this->message('Created Permission: '.$installer_permission['name']);
            }
        }
        
        
    }

The question is: How do Fields, Templates and Fieldgroups interact?

What is the best way to install fields and then add them - grouped by fieldgroups - to the desired template?

Is it even required to group fields when adding to templates?

Greetings,

Martin

Link to comment
Share on other sites

1 hour ago, Gadgetto said:

What is the best way to install fields and then add them - grouped by fieldgroups - to the desired template?

You seem to be confusing Fieldsets and Fieldgroups. They are very different things. Fieldsets are special fields to help you group fields together for the purposes of how they are displayed on a page during edit. In a sense, they group the Inputfields of the fields within the Fieldset. Each Fieldset is then displayed in its own tab during page edit. As usual though, the order or even the presence of fields on a page have no bearing on their appearance in the frontend. 

Back to the main question, I quote the definitions of Fields, Fieldgroups and Templates as per the docs:?

Fields

Quote
Field represents a custom field that is used on a Page.

That just means a database table, that is created via ProcessWire using a defined schema and installed as a module. You can read more about them here.

Fieldgroups

Quote
Fieldgroup is a type of WireArray that holds a group of Field objects for template(s).

You will rarely have to interact directly with Fieldgroups. Each template you create has a corresponding Fieldgroup. A Fieldgroup just says these are the fields available in this template. Hence, it is possible to reuse a field across different templates (i.e. across different Fieldgroups). More about them here.

Templates

Quote

Template is a Page’s connection to fields (via a Fieldgroup), access control, and output via a template file.

This one is self-explanatory, me thinks ?. More about them here.

Edited by kongondo
  • Like 3
Link to comment
Share on other sites

I guess @Gadgetto is talking about how to create/edit/remove/move/etc fields/templates/pages/etc. when they are necessary for an installable and reusable module? Then pages import/export is no option.

You can have a look here how you can do that: https://github.com/nicoknoll/MarkupSEO/blob/master/MarkupSEO.module#L971-L1095

  • Like 2
Link to comment
Share on other sites

3 hours ago, Gadgetto said:

I'm just working on the installer for a bigger module which will need many fields + some templates.

Sometimes a module does need to create fields, templates and pages but it would be the exception rather than the rule. Most Process modules, even complex ones with multiple (pseudo) sub-pages such as Admin Actions, do not create fields, templates or pages other than the single page used to execute the Process.

Instead they use multiple execute() methods that work via URL segments. The forms on those pseudo sub-pages don't save data to PW fields but save all the module-related data to the module's config (stored as JSON in a single field in the database). The "nav" array in the module info takes care of creating the navigation to sub-pages.

But perhaps you already know this if you've studied ProcessHello and other Process modules.

Some off-the-top-of-my-head cases where you probably would need real fields/templates/pages for a module:

  • You want to store files or images for use with the module.
  • You want to use a Repeater and don't want the extra work to create to repeatable input type in the Process module.
  • You want to store a larger amount of data than is allowed for in the TEXT column type used for module config data (although alternatively your module could create a dedicated table to store its data).
  • Like 3
Link to comment
Share on other sites

3 minutes ago, Robin S said:

Sometimes a module does need to create fields, templates and pages but it would be the exception rather than the rule.

That might be true, but IMHO that's a huge limitation of PW. I've had the need to create fields/templates/pages a LOT over time. Many of us are now doing it manually (creating fields on dev, then importing them on the live system). We also have the Migrations module, but that's only half as good as it could be. At the moment it is really hard to develop modules that ship with a certain setup of fields/templates/pages and maybe on later versions upgrade those settings.

I'm thinking for a long time now of a new kind of API that makes these operations a lot easier (adding and removing fields/templates/pages etc. is not easy, especially if you need to take care of collisions (field already exists, can't remove field because it's used by a template etc.).

If anyone is interested in helping on developing such a module - similar to the Migrations module - send me a message.

  • Like 1
Link to comment
Share on other sites

3 hours ago, Gadgetto said:

I'm just working on the installer for a bigger module which will need many fields + some templates. 

What Robin said above.

In addition, sometimes you don't need many fields, but just many inputs. I don't know how comfortable you are with PHP and you would need to study ProcessWire Fieldtype modules, but rather than have lots of fields that do small things, sometimes it is easier and more efficient to create custom fields whose (database) columns will hold your many inputs. For instance, rather than have a field each for first_name, last_name, middle_name, telephone_1, telephone_2, hobbies, profession, etc...you can create one custom field that will hold all these related data with each piece a column in that field. In ProcessWire-speak, those columns are subfields which you could access using the API as $myField->firstName, $myField->lastName and in selectors like so, my_field.first_name, my_field.last_name.

Just thought to throw this in there, just in case.

Link to comment
Share on other sites

3 minutes ago, bernhard said:

We also have the Migrations module, but that's only half as good as it could be.

That's a special case because it's a module that is all about PW fields, templates and pages - indeed anything in the PW API.

Generally speaking, if your publicly-shared module needs to collect and store some data then fields/templates/pages is not the way to go. It's messy, it's not self-contained, and it's liable to cause a headache for uninstalling and upgrading (what if a user adds or removes fields from your module templates?).

Link to comment
Share on other sites

4 minutes ago, bernhard said:

That might be true, but IMHO that's a huge limitation of PW. I've had the need to create fields/templates/pages a LOT over time. Many of us are now doing it manually (creating fields on dev, then importing them on the live system). We also have the Migrations module, but that's only half as good as it could be. At the moment it is really hard to develop modules that ship with a certain setup of fields/templates/pages and maybe on later versions upgrade those settings.

I'm thinking for a long time now of a new kind of API that makes these operations a lot easier (adding and removing fields/templates/pages etc. is not easy, especially if you need to take care of collisions (field already exists, can't remove field because it's used by a template etc.).

@bernhard, I'm not sure, but I think this is a different issue from what @Robin S stated. I think the point was that, modules do not have to create fields, etc, unless they need them. Now, how those fields, templates and pages are created is a different issue. Not wishing to OT this topic, IMHO, we do already have the API for creating, deleting and checking for field and template collisions. Regarding the former two, we have the normal/older method of new Field() and the newer setImportData() [OK, you would need to export the JSON first, but that's a one off thing]. As for collisions, it is a simple as getting the field; if a field was found; then abort. Maybe I'm not getting the point, and we'd need to discuss this in a different thread anyway ?

Link to comment
Share on other sites

So you think MarkupSEO would be better as a single Fieldtype having all those inputs and storing it in one db table? I don't think so, but maybe I'm wrong, so I'm curious to hear your and other's thoughts.

What about creating a blog module where you can add new blog posts that have a title, content, publish date, date, image gallery etc etc. - create a fieldtype for that or just use PW's core fields and put them together in one template, setting a parent template to allow only these kind of pages as children.

What about creating a slider module? Using a repater with images and text fields for headlines. That's easy using core fields. But the problem is that we are always building custom solutions that we can not reuse in other projects. Because it's so easy to create fields/templates/pages in the admin GUI, but it's so hard to create then via code (compared to the GUI).

Using Migrations is a first step in the right direction, but you cannot split those migrations up to several places (meaning: modules). IMHO that's a real problem.

4 minutes ago, Robin S said:

It's messy, it's not self-contained, and it's liable to cause a headache for uninstalling and upgrading (what if a user adds or removes fields from your module templates?).

Exactly. At the moment! I wished there was a better way. Something like migrations for each separate module. I mean... Fields are the way to store all the user input in processwire, so I think it's a real problem that we cannot properly use that core features easily in our modules.

Link to comment
Share on other sites

3 minutes ago, kongondo said:

Regarding the former two, we have the normal/older method of new Field() and the newer setImportData() [OK, you would need to export the JSON first, but that's a one off thing]

JSON export/import IMHO is really not a good way of doing that programmatically. There are always situations where you FIRST need to have the templates existing and THEN you set the correct settings. You can't do that in one step. Simple example:

- create template "blogposts"
- create template "blogpost"
- set allowed children for "blogposts" to "blogpost", parents to "home"
- set allowed parents for "blogpost" to "blogposts", parents to none

You simply can't do that via import/export, can you?

9 minutes ago, Robin S said:
18 minutes ago, bernhard said:

We also have the Migrations module, but that's only half as good as it could be.

That's a special case because it's a module that is all about PW fields, templates and pages - indeed anything in the PW API.

Reading this I have to clarify: Didn't want to say that the module is bad in any way. The module is great, but the situation we have is not great...

  • Like 1
Link to comment
Share on other sites

1 minute ago, bernhard said:

So you think MarkupSEO would be better as a single Fieldtype having all those inputs and storing it in one db table? I don't think so, but maybe I'm wrong, so I'm curious to hear your and other's thoughts.

I'm assuming this is addressed to me? I've never used that module so can't comment much. What I meant was that sometimes some data is just related and it makes sense to have them in one field, similar to the example I gave. Assuming that was some customer's or  member's data, with one simple query, I have all their info rather than querying several tables to get info about one entity. 

4 minutes ago, bernhard said:

What about creating a blog module where you can add new blog posts that have a title, content, publish date, date, image gallery etc etc. - create a fieldtype for that or just use PW's core fields and put them together in one template, setting a parent template to allow only these kind of pages as children.

Interesting you mention this. It's something I've thought about previously. If I had to redo the Blog module, I would combine some of the fields.

What do you see as drawbacks to combing/collapsing related fields into one field, storing their data as columns? Technically, the database doesn't care. Yes, some people (me included) hate horizontal scrolling when viewing databases, but it's not a thing one does daily ?.

Link to comment
Share on other sites

2 minutes ago, kongondo said:

I'm assuming this is addressed to me? I've never used that module so can't comment much. What I meant was that sometimes some data is just related and it makes sense to have them in one field, similar to the example I gave. Assuming that was some customer's or  member's data, with one simple query, I have all their info rather than querying several tables to get info about one entity.

It's a perfect example of what I'm talking about: It creates these fields:

FMAUbZP.png

And as you can see in this example it automatically adds these fields to two selected templates. These tasks are really not as easy to develop as they could (should) be imho. Once installed, you can then input data on all pages with selected templates:

6qmIhaa.png

You can't do that using process modules, or am I missing some concept here? There are MANY use cases for this.

5 minutes ago, kongondo said:
12 minutes ago, bernhard said:

What about creating a blog module where you can add new blog posts that have a title, content, publish date, date, image gallery etc etc. - create a fieldtype for that or just use PW's core fields and put them together in one template, setting a parent template to allow only these kind of pages as children.

Interesting you mention this. It's something I've thought about previously. If I had to redo the Blog module, I would combine some of the fields.

Your example of an address field would maybe make sense to be combined in one new fieldtype. But in many cases I think this is not the best option.

6 minutes ago, kongondo said:

What do you see as drawbacks to combing/collapsing related fields into one field, storing their data as columns? Technically, the database doesn't care.

I care! Developing a new Fieldtype is a lot more effort than just creating fields, assigning them to templates and creating new pages! But as soon as you want to make that process reusable (eg for dev/staging setup)/revertable you need to use something like the migrations module. But what if you wanted to use 3 of the fields that you created via migrations in another project? Bad luck, not possible - or is it?

  • Like 1
Link to comment
Share on other sites

4 minutes ago, bernhard said:

There are always situations where you FIRST need to have the templates existing and THEN you set the correct settings. You can't do that in one step. Simple example:

I agree, and this is a situation I've encountered. I just do what can be done with JSON, the rest I do using other API, as an after-step.

15 minutes ago, Robin S said:

It's messy, it's not self-contained, and it's liable to cause a headache for uninstalling and upgrading (what if a user adds or removes fields from your module templates?).

I beg to differ. I don't get the point about being messy. If you have an installer and an uninstaller, that covers the job. The blog module, for instance, needs to store preferences data somewhere. Whether these are stored as data in a field on a page, or in the modules config, they all end up in the database and are transparent to the user. Storing such preferences in a file (I'm not saying that is what you are suggesting) seems inefficient to me and prone to error, i/o.  

19 minutes ago, Robin S said:

what if a user adds or removes fields from your module templates?

I don't think this is a problem at all. You always remove templates first (after deleting your pages, of course). It doesn't matter if it has fields, using the API, the template will be removed. You then delete the fields you installed. Coupled with clear documentation and a big warning sign on the module's config page, there shouldn't be any cause for confusion. This is how I do it in all my bigger modules. In addition, my uninstall routines do not automatically remove the fields and templates created by the module. Instead, there is a cleanup page accessible only to superusers. If they hit 'remove' having read the warnings, it means they know what they are doing.

I'd love to hear your opinions regarding storage of module data, though.

  • Like 1
Link to comment
Share on other sites

3 minutes ago, bernhard said:

And as you can see in this example it automatically adds these fields to two selected templates. These tasks are really not as easy to develop as they could (should) be imho. Once installed, you can then input data on all pages with selected templates:

I see. Seems like a special case, especially the bit about adding the fields to two selected templates. I might have a peek at the module if I get some time.

Link to comment
Share on other sites

Just now, kongondo said:

I see. Seems like a special case, especially the bit about adding the fields to two selected templates. I might have a peek at the module if I get some time.

I don't think that this is a special case at all. Imagine a slider module that could help us to create an image slider for our websites. It could create the markup (maybe let the user choose the css framework) and it could also create the necessary fields in the admin and add those fields to the templates that should display a slider.

I've had lots of those situations finding myself copying and pasting code snippets from one site to another. Finding a bug in one page, having to fix it in all my sites manually etc etc. Now, that's what I call messy ? 

If we had a proper API that made those tasks easy, I think we would get a lot more reusable modules just like the SEO module, because then it would be a lot easier to create such modules and push fixes, changes or updates. And upgrading existing projects would only be one click (or git pull).

10 minutes ago, kongondo said:

This is how I do it in all my bigger modules. In addition, my uninstall routines do not automatically remove the fields and templates created by the module. Instead, there is a cleanup page accessible only to superusers. If they hit 'remove' having read the warnings, it means they know what they are doing.

Agree! I've learned a lot from your modules. But I still think the API need one abstraction layer on top of that. See for example how hard it is to edit a field in template context: https://processwire.com/talk/topic/6656-change-field-description-in-context-via-api/

It should be somethink like this, imho:

$api->editInTemplateContext('mytemplate', function($field) {
  $field->label = 'Custom label for mytemplate';
});

The migrations module offers some of those helpers. It's one step. But there is at least one more step missing...

  • Like 1
Link to comment
Share on other sites

Seems like we're talking about a couple of different things here:

1. Making certain "things" (don't think I can be more specific than that) reusable in multiple projects that you work on now and in the future. These are for in-house use by a single developer or team of developers and not shared publicly with the PW community (in the modules directory for instance). You could try and use modules for this purpose (I think this is what @bernhard is interested in) or any number of other approaches. This is stuff that's very much down to individual workflow preferences and I don't think the PW core can provide easy solutions that are going to suit everyone.

2. Modules that are shared publicly with the PW community. This is totally a matter of opinion, but personally I'm not enthusiastic about things like sliders and blogs being packaged and distributed as modules. In seems very WordPressy and not really the PW way (teach a man to fish, etc). A module could provide some building block that is useful for making a slider or a blog but it shouldn't do things like try and anticipate all the fields a user needs, output all the markup, bundle third-party JS libraries and suchlike. The beauty of PW is that it's so quick and easy to build solutions that are exactly tailored to the project at hand with nothing unnecessary left lying around. And while developing these solutions you're always learning how to be a better developer. A plug-and-play module that outputs whole pieces of the website works against that IMHO.

  • Like 5
Link to comment
Share on other sites

25 minutes ago, Robin S said:

This is totally a matter of opinion, but personally I'm not enthusiastic about things like sliders and blogs being packaged and distributed as modules. In seems very WordPressy and not really the PW way (teach a man to fish, etc). A module could provide some building block that is useful for making a slider or a blog but it shouldn't do things like try and anticipate all the fields a user needs, output all the markup, bundle third-party JS libraries and such like

This is an interesting thought. My opinion has always been:

teach a man/woman to fish = pw core and API (basically, /wire/)
man/woman fishing = /site/

So, modules, or as others call them, custom plugins, are exactly where the fishing should be happening. I don't find it at all WordPressy since ProcessWire's (custom) modules, unlike WordPress's, are not the cobbling together of disparate things to provide a solution to a problem that should have fundamentally been resolved by the core. 

25 minutes ago, Robin S said:

The beauty of PW is that it's so quick and easy to build solutions that are exactly tailored to the project and hand with nothing unnecessary left lying around.

Agreed, but therein also lies the beauty of reusability. If I find myself building blogs with every/most sites that I build, it makes sense to package the blog solution. In other words, modules ?.

The point about second-guessing what fields a user needs is a good one, but it is not one without a solution. This is easily solved (again, back to blog module) by a 2-step installer that asks what fields the user needs. We also have Fields like Table and DynamicSelects that allow you to add/remove fields/columns even post-install.  

  • Like 4
Link to comment
Share on other sites

Thx @Robin S, interesting points.

As always it's not black/white - the question is how far one can/should go in terms of packing things into a module vs. building it from scratch all the time via the API.

IMHO there are standard things like blogs, forum, sliders, guestbook etc. that are not that easy and quickly to create with PW and therefore cost a lot of time and money on my end. I wished I had more reusable products for such tasks. And I'm working on it.

On the other hand I love the freedom of PW. But I think both worlds can live well together in our universe. And that might be another argument for using regular fields over custom fieldtypes @kongondo: When using regular fields, the user can easily customize those templates to their very own needs. Imagine a blog module that ships with fields

  • blog_title
  • blog_date
  • blog_content
  • blog_gallery
If the user needed a field to store files he could either create a PR with an update script (again both migrations and export/import would not work) or create this single field on his own and just use it for himself. This would not be that easy if those 4 fields where wrapped in a single custom blog fieldtype (that would be the WordPress way of a plugin).
 
Do you understand what I'm trying to say? ? Not trying to convice anybody here - just enjoying to get valuable input as this is in my head for quite a long time...
  • Like 1
Link to comment
Share on other sites

50 minutes ago, bernhard said:

or create this single field on his own and just use it for himself.

By the way, this is what we are currently doing with Media Manager. If you add a field to a media manager (in-house) template, media manager will find it and will make it accessible to you via its API. Essentially it means you can use Media Manager for a whole range of things. 

  • Like 1
Link to comment
Share on other sites

13 hours ago, kongondo said:

You seem to be confusing Fieldsets and Fieldgroups. They are very different things. Fieldsets are special fields to help you group fields together for the purposes of how they are displayed on a page during edit. In a sense, they group the Inputfields of the fields within the Fieldset. Each Fieldset is then displayed in its own tab during page edit. As usual though, the order or even the presence of fields on a page have no bearing on their appearance in the frontend. 

Back to the main question, I quote the definitions of Fields, Fieldgroups and Templates as per the docs:?

Fields

That just means a database table, that is created via ProcessWire using a defined schema and installed as a module. You can read more about them here.

Fieldgroups

You will rarely have to interact directly with Fieldgroups. Each template you create has a corresponding Fieldgroup. A Fieldgroup just says these are the fields available in this template. Hence, it is possible to reuse a field across different templates (i.e. across different Fieldgroups). More about them here.

Templates

This one is self-explanatory, me thinks ?. More about them here.

Hi @kongondo I don't think I'm confusing Fieldsets and Fieldgroups. My question was regarding 'fieldgroups' and how they interact with fields and templates when installing things via API. I found a code sample in your MenuBuilder module where you do the same:

https://github.com/kongondo/MenuBuilder/blob/b06c8903fea51b197752b8f10bdd15191efe7ad4/ProcessMenuBuilder.module#L2878-L2917

The problem is, I don't really understand why this is needed and for what.

Link to comment
Share on other sites

12 hours ago, Robin S said:

Sometimes a module does need to create fields, templates and pages but it would be the exception rather than the rule. Most Process modules, even complex ones with multiple (pseudo) sub-pages such as Admin Actions, do not create fields, templates or pages other than the single page used to execute the Process.

Instead they use multiple execute() methods that work via URL segments. The forms on those pseudo sub-pages don't save data to PW fields but save all the module-related data to the module's config (stored as JSON in a single field in the database). The "nav" array in the module info takes care of creating the navigation to sub-pages.

But perhaps you already know this if you've studied ProcessHello and other Process modules.

Some off-the-top-of-my-head cases where you probably would need real fields/templates/pages for a module:

  • You want to store files or images for use with the module.
  • You want to use a Repeater and don't want the extra work to create to repeatable input type in the Process module.
  • You want to store a larger amount of data than is allowed for in the TEXT column type used for module config data (although alternatively your module could create a dedicated table to store its data).

I want to create a full featured Newsletter mailing system with subscription/unsubscription pages, profile edit pages, some backend pages for Newsletter creation, Newsletter handling (sending + CRUD).

  • Like 1
Link to comment
Share on other sites

12 hours ago, bernhard said:

If anyone is interested in helping on developing such a module - similar to the Migrations module - send me a message.

I'm definitely interested in developing such a module, but I'm afraid my knowledge of ProcessWire isn't nearly enough... ?
But I would be happy to contribute my ideas. 

In general, I think it would be better if it were included in the ProcessWire API.

  • Like 1
Link to comment
Share on other sites

Wow, I didn't expect such a response.I didn't mean to spark a principle discussion.

To create clarity:

I want to create a full featured Newsletter mailing system with subscription/unsubscription pages, profile edit pages, some backend pages for Newsletter creation, Newsletter handling (sending + CRUD + settings). So I'll definitely need to install fields, templates and pages.

Thank you very much for all your tips and hints, but I still don't know what's the best way to install fields and add them to templates via API.

Especially the Fieldgroup class gives me headaches:

https://processwire.com/api/ref/fieldgroup/

If you have a look at @kongondos MenuBuilder module you can see how he uses a fieldgroup to add fields to a template:

https://github.com/kongondo/MenuBuilder/blob/b06c8903fea51b197752b8f10bdd15191efe7ad4/ProcessMenuBuilder.module#L2878-L2917

Are Fieldgroups required for adding fields to templates? What are these for?

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...