Robin S

Connect Page Fields

Recommended Posts

ConnectPageFields

A module for ProcessWire CMS/CMF. Allows the connecting of two related Page fields so that changing one updates the other.

Purpose of module

An example: suppose your website is about movies. You have a template "movie" with Page field "actors". For each movie you add the actors that appear in the movie. All good, but what if you want to find results like...

  • the 10 actors who have appeared in the most movies
  • actors who haven't appeared in any movies since 1990

You cannot retrieve these pages with a single efficient $pages->find() query, and must load a large PageArray into memory in order to iterate or filter it. For the sake of making these types of queries more efficient you could structure your templates/fields so that movies are added to actors instead, but this may be a less comfortable workflow and can run into equivalent problems (e.g. "find the 10 movies with the largest cast").

The solution is to have a two-way relationship so that movie pages have an "actors" Page field and actor pages have a "movies" Page field. This module will keep these two Page fields in sync so that adding "Ryan Gosling" to "Drive" automatically adds "Drive" to "Ryan Gosling".

Also, you can select the same Page field in both PageField A and PageField B. For example, create a "Related" Page field for related pages. Choose "Related" for both fields in a pair in the module config. Now when you add "Orange buffoon" to Related for "Donald Trump", "Donald Trump" is automatically added to Related for "Orange buffoon".

Usage

Install the ConnectPageFields module. If you haven't already done so, create the two Page fields you want to connect and add them to templates.

In the module select the two Page fields in a "Connected field pair" row as PageField A and PageField B.

You can define up to 20 pairs of connected Page fields. Use the "Number of connected field pairs" field to add rows as needed.

Troubleshooting

Make sure you have set the "Selectable Pages" settings for each Page field correctly:

  • The settings for PageField A should allow pages using the template(s) that PageField B has been added to.
  • The settings for PageField B should allow pages using the template(s) that PageField A has been added to.

 

http://modules.processwire.com/modules/connect-page-fields/
https://github.com/Toutouwai/ConnectPageFields

 

Module config:

connect-config.png

 

Demo showing how changing one Page field updates the other:

connect-page-fields-2.gif

Edited by Robin S
New config system
  • Like 31

Share this post


Link to post
Share on other sites

Updated to v0.0.2. This version simplifies the module somewhat and you no longer need to select templates in the config.

  • Like 5

Share this post


Link to post
Share on other sites
7 hours ago, fbg13 said:

Might be worth mentioning that it works with the same field too.

Sounds interesting. Can you give an example of how that could be useful?

Maybe something like a Friends field? On page "Bob", "Sue" is added to Friends - so on page "Sue", "Bob" is automatically added to Friends. Just trying to think through the different use cases for the module.

Share this post


Link to post
Share on other sites
23 minutes ago, Robin S said:

Can you give an example of how that could be useful?

For pages related to same kind of pages: movies (Ironman related to Ironman 2, Avengers etc), books, games, tutorials, recipes...

If i write IronMan with space between the words i get V@g1n@ Monologues wtf :huh:

  • Like 2

Share this post


Link to post
Share on other sites
18 minutes ago, fbg13 said:

For pages related to same kind of pages: movies (Vagina Monologues related to Ironman 2, Avengers etc), books, games, tutorials, recipes...

Got it, thanks. And your interpretation of those movies clearly goes much deeper than mine :D

  • Like 3

Share this post


Link to post
Share on other sites
On 09/11/2016 at 0:04 AM, fbg13 said:

Well for some reason IronMan with space between the words gives me that no idea why.

Might have caught a virus.

Cough. We used to get a lot of spam with certain movie names on the forum. That's a feature.. kind of :)

  • Like 2

Share this post


Link to post
Share on other sites

hi robin,

totally missed your module and created my own... 

maybe you have more time than i have and compare them? seems yours does exactly the same than mine. maybe more efficient because i'm using nested foreach...

Share this post


Link to post
Share on other sites

Nice thanks for this great module! Don't have a use right now but I remember that I wished something like that some time ago, will for sure come in handy sooner or later

  • Like 2

Share this post


Link to post
Share on other sites

With AdminOnSteroids the delete checkbox position absolute is overwritten.Untitled.png

Can you make the css selector more specific or use !important?

.Inputfields .InputfieldFieldset li[class*="Inputfield_delete_"] {
	position: absolute!important;
}

 

Share this post


Link to post
Share on other sites
1 hour ago, fbg13 said:

With AdminOnSteroids the delete checkbox position absolute is overwritten.

Thanks, fixed in latest commit.

  • Like 2

Share this post


Link to post
Share on other sites
On 8.11.2016 at 11:30 PM, Robin S said:

Got it, thanks. And your interpretation of those movies clearly goes much deeper than mine :D

Sorry guys, I have been laughing five minutes alone here for your vagina monologues vs avengers debate :D 

It was indeed our link spam protection plan (that actually worked pretty well). So @fbg13 no worries about any virus, just poor humor from moderators. 

  • Like 2

Share this post


Link to post
Share on other sites

Hi @Robin S, I'd like to know if this modules works with API calls, or just within the admin page? Assuming I have a properly setup pages called cards and members that reference each other, and I write something like:

 

$member = $pages->get(123);
$card = $pages->get(456);
$card->members->add($member);
$card->save();

echo $member->card->title;

 

Should I expect the code to output the card's title? I actually tried it out and it didn't work. But maybe I'm just doing something wrong. The fields work okay when setting them using the page editor. Thanks. :)

 

 

Share this post


Link to post
Share on other sites
On 24/04/2017 at 7:07 PM, Alxndre' said:

I actually tried it out and it didn't work. But maybe I'm just doing something wrong. The fields work okay when setting them using the page editor.

Hi @Alxndre', I've been away for a bit so just following up now. Yes, the module works with both API and admin changes. In your code example you need to set the output formatting of $card to false before attempting to set values to a field.

Share this post


Link to post
Share on other sites

How can I trigger the module for all pages (with paired fields) at once? Like mass-updating all pages? Setting field to itself doesn't work

foreach($pages->find('template=post') as $p) {
    $p->of(false);
    $p->tags = $p->tags;
    echo $p->save();
}

// doesnt work

because the module skips the page if none of the paired field is changed

public function updatePageFields(HookEvent $event) {

    // ...

    foreach($flds as $fld) {

        $this_fname = $fld->name;

        // only if the page is not still null and the field has changed
        if(!$page->id || !$page->isChanged($this_fname)) continue;

		// ...
        }
    }
}

 

 

tags.png

Share this post


Link to post
Share on other sites
On 20/08/2017 at 0:07 PM, abdus said:

How can I trigger the module for all pages (with paired fields) at once? Like mass-updating all pages?

Sorry for the late reply; I have been on holiday for a while. :)

This module acts only on changes to a Page Reference field - this is deliberate for reasons of efficiency.

If you already have some Page Reference values in place before you start using the module on those fields then you can get things set up with a one-off API operation:

// Get all pages where page_field_a is not empty
$pgs = $pages->find("page_field_a.count>0");
foreach($pgs as $p) {
    // For this page, get the pages selected in page_field_a
    $selected_pages = $p->page_field_a;
    foreach($selected_pages as $selected_page) {
        // Add this page to page_field_b on the selected page
        $selected_page->of(false);
        $selected_page->page_field_b->add($p);
        $selected_page->save();
    }
}

You can do a similar operation for page_field_b -> page_field_a if needed.

Once you set up the Page Reference field pair in the module config then the module will take care of all changes from that point onwards.

  • Like 2

Share this post


Link to post
Share on other sites
8 hours ago, Robin S said:

I have been on holiday for a while.

Yeah, we've been missing you :) welcome back to the best community support forum on Earth.

  • Like 1

Share this post


Link to post
Share on other sites

This module was suggested by @abdus to me in another post and after giving it a whirl, it's pretty awesome! If you link one way, it makes sense for pages to be linked the other way also.

  • Like 2

Share this post


Link to post
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.