Jump to content

Best practices


Recommended Posts

ProcessWire is unopinionated. I get that. It’s a good thing.

And yet, this lack of proscription can be bewildering to newbies like me who struggle to figure out how best to accomplish something — even a simple something.

Case in point:

I’ve created an “organizations” template, and have added a couple of obvious fields to it (sortTitle (fieldText), address (fieldStreetAddress), etc.).

Now I realize that I have a bunch of similar-but-distinct bits of information that I’d like to store for each organization — basically, various competing “unique identifiers” such as PURLs, DOIs, ORCids, that kind of thing. Each organization will have 0–n  of these, and I’m sure that over the years, more such IDs will crop up, and I’ll want to easily add new ones.

  1. So, I could define lots of different FieldTexts (one for each type: ORCid, DOI, etc.), most of which would be empty for most organizations. And then I could continue adding new ones over the years. This seems less than graceful.
  2. Or I could (I think) define a repeating field — though I’m pretty sure that would allow me to collect values of such IDs, without saying what kind of ID each was (am I right?), so that wouldn’t be a good plan.
  3. Or I could define a FieldSet, which might be more efficient (since it’s just one field), but would have the same long-term drawbacks that using lots of FieldTexts would have.
  4. Or I could use a ProField Table … I think. (I’ve purchased ProFields for other reasons, so I’ve no reluctance to go this route if it makes sense.)
  5. Or I could create a “Unique Identifier Code (UIC)” template with N FieldTexts defined on it, and could create a new UIC page for each organization that had any kind of UIC.

I’m sure there are more options, too — possibly including the best choice. I’ve read (and done!) many of the tutorials, dozens of full forum threads, all of the relevent official documentation, and many module descriptions … and I feel like I know less than I did when I started.

So my questions are two:

  1. What would you do — and why?
  2. Is there somewhere where the community has assembled a list of broadly-agreed-upon best practices for ProcessWire development? Something along the lines of Ryan’s PHP Coding Style Guide?

Thanks in advance for all constructive suggestions. I’ve now read a lot of threads in this forum, and I have to say that I’m very impressed with the friendliness of the community, and with the exceptionally high signal-to-noise ratio here. I’ll try not to add too much noise!

  • Like 1
Link to comment
Share on other sites

I don't think there is a "best practice" written down somewhere for this sort of scenario. I agree it can be confusing to figure out the "right solution" when there would seem to be so manyw ays to achieve the same. 

If all the values from the identifier are okay with being a text type value, I would go with a Table field with two columns, a Page Reference that fills its options with the "catalogue" of "possible IDs" and a text field that acts as the field for the actual value, this way you can have whatever fields you want on each organization, and you can do stuff like:

$pages_with_purls_identified_orgs = $pages->find('template=organization, ids_table.id_type.name=purls');

This also guarantees you can also add new identifiers in the future very easily and consistently. 

You could do almost exactly the same with repeaters. Why table and not repeater? I just prefer the interface of the table field, I think it's less clunky visually when few fields are involved and has a more snappy feel. If each identifier would need more data added, I'd go for a repeater, but since it seems it's just an ID name and the actual value, table field seems enough.

Repeaters would also have the "overhead" of loading an extra page on memory per repeater, since each repeater item is a processwire page. 

Although another scneario, what if the value of each identifier is a different type, then the table field would not work as nicely. Say you need DOI to be alphanumeric and ORCids to be integers, maybe for this case a repeater could work, with the same catalogue of identifiers, except that you create two additional fields (one text type, one integer type) and show them conditionally depending on the value of the page reference field where the type of identifier is selected. Please take this idea with a grain of salt, just something I came up with right now. It might be a hassle to manage the relationship of "identifier - type of value" on the actual code, or it might be worth the trouble, or there might be a better solution out there ?


  • Like 6
Link to comment
Share on other sites

@ErikMH Great question. I think elabx has pretty much covered the repeater and table options - both of which work really well. So I'll skip these and just mention a couple of other possibilities, both of which I've used in various sites (in addition to the table and repeater fields)

  • Child pages
  • Repeater Matrix


Child Pages

It might be possible, depending on you application, just to use child pages to house your set of related items. This won't be the case if you intend using the page url structure for something specific on your site, but if you aren't then you can set up a template per type (one each for purls/orcids etc) and use the template family relationship to restrict the parent-child relationship as needed. Thereafter you would just add child pages to each of your organisations. I use this method in my little invoicing system for the payment methods accepted by each of my personas:


Output in the API is simple, just iterate over each of your page's children to produce your output:



Repeater Matrix

If you have access to the ProFields package, this is probably slightly easier than using regular repeaters as you get to specify the allowed "types" of the items when constructing the field. I also find the interface more intuitive than normal repeaters and the rendering is particularly nice as it allows each item's code to be in its own PHP file.

In the case you mentioned (Organisation with 0-n links or IDs of vaious types) I would probably go with a repeater matrix or the Table field as mentioned by elabx.

  • Like 3
Link to comment
Share on other sites

@elabx and @netcarver, thank you both so much for your detailed and well-reasoned responses. These were just what I was hoping for! As I said at the outset, I do appreciate PW’s flexibility — but it does mean there’s a lot to process mentally before really getting going on one’s first project.

Of the four strategies you mentioned (a repeater, a table, child pages, and a repeater matrix), I think I’d have to agree with Netcarver that a table or a repeater matrix sound like the best match for my needs. Child pages (though a fascinating approach that I hadn’t thought of) won’t work because I do have another need for the page hierarchy. And repeaters just don’t “feel” right somehow.

So while I mull that over, does anyone have much experience with ProFields TextAreas? I stumbled across these yesterday, and have experimentally set one up to hold a batch of “note”-type TextArea fields — very similar to Ryan’s example — and it’s working really well with my half-dozen test pages. Again, it “feels” like this might also be an excellent match for my needs with Text fields, but I’m curious as to why you didn’t suggest it. (Simply not having thought of it is a perfectly acceptable answer, of course: So.Many.Options!)


Link to comment
Share on other sites

@ErikMH I don't have much experience with that field type, so I'll put this as a question...

Do you mean that you could set it up so that each company had a Profield Textarea field with N "areas"; one for each type of identifier, and then you literally enter each PURL (say) on one row in the PURL area? If that's the case, and you don't need to have any kind of random/manual order of the different types of IDs, then I suspect that could work well if there were no difference in the way you want to render each line from those areas in your output.

One area where going down the repeater/matrix route would be beneficial is for more complex types - but for a simple ID that wouldn't be needed.

Link to comment
Share on other sites

1 hour ago, ErikMH said:

but I’m curious as to why you didn’t suggest it.

I think I just have never used it before haha, but from what I know of it it does look like it could do the work.  

Link to comment
Share on other sites

Just a totally different approach in terms of ... creating a new template of some kind.

Whenever I start a new project I look up possible definitions, and standards I could need and use within that project.

For example schema.org, microformats, and similar... events, corporations, business, personal data, whatever... most of the time I find things I could use from all around the web. In some cases I call our chamber of commerce and similar for details about things they save, have to save or need to save about companies of all kind. Sometimes I even talk to my accountant, my lawyer and other similar "institutions"... whoever can help me. Sometimes the niche even has standards defined I can use and therefore I use them (for example: book stores).

Then... whenever I set up a new templates for whatever data-object I need to save... I keep it flat... I don't care if a template has 10 or 100 fields... (books are a perfect example here). I need those details each and everywhere therefore I don't want to work with if/else, case, joins or whatever to get my details. I only reference small bits and only those I really have to and want to reference (authors of books, form of organization, and similar).

Just my two cents.

  • Like 2
Link to comment
Share on other sites

On 6/10/2021 at 8:49 PM, ErikMH said:

does anyone have much experience with ProFields TextAreas? I stumbled across these yesterday, and have experimentally set one up to hold a batch of “note”-type TextArea fields — very similar to Ryan’s example — and it’s working really well with my half-dozen test pages.

Hi, I used this one a lot, but before you go further with it: It has one disadvantage. You have to use one type for all fields (subfields). So, pretty fine to use textarea for text and textarea, but there is already a new fieldtype out that makes the textareas obsolete. It is called Combo and since yesterday available in version v6beta.

As you said: So.Many.Options! ?

The only part that seems to be different, what I got so far til now, (started exploring / reading with / about COMBO two weeks ago), is a difference with searching / finding results in multi language sites. Whereas all (?) other (text)fields have a sort of scoped language pools where the search engine by default only searches in one language, the current active language, with the Combofield this is not possible. With other fields you can manage from the API site to search in more than one language of course, or in another then the current language. So ATM I stuck at if I should call this an advantage of the Combofield (in some situations) or more a disadvantage. At least, ATM it seems a significant difference that needs attention when planning a sites field setup in multi language sites with FE search functionality.


  • Like 4
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

  • Recently Browsing   0 members

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