Jump to content

Matching 2 pages based on title and "combining" data


Recommended Posts

So I am making a front-end dashboard for an internal project, and was curious if it is possible to match 2 pages together based on their title and retrieve the data.

To make it more clear:

I have two pages "Section A"  and "Section B" that each has child pages with names (the specific person) with subpages for their services offered. 


Section A
	- John Doe (name=john-doe)
		- Service 1
		- Service 2
		- Service 3
	- Jane Doe (name=jane-doe)
		- Service 1
		- Service 2
		- Service 3
Section B
	- John Doe (name=john-doe)
		- Service 4
		- Service 5
		- Service 6
	- Jane Doe (name=jane-doe)
		- Service 4
		- Service 5
		- Service 6

What I would like to achieve on the front-end (if it is even possibile), is an output like:

John Doe
	- Service 1
	- Service 2
	- Service 3
	- Service 4
	- Service 5
	- Service 6
Jane Doe
	- Service 1
	- Service 2
	- Service 3
	- Service 4
	- Service 5
	- Service 6

Thinking aloud: use a find to get all pages using the template "service user" and then foreaching through their children (and possibly getting a few field values as well) to output in the front end. The service templates used in the sections vary slightly in which fields they use.

<?php $findUsers = $pages->find("template=service-a (and or) service-b,(some how match based on names)"); //if no match exists, output what is available ?>

	<ul>
		<?php foreach ($findUsers as $groupedUser): ?>
			<li><?php echo $groupedUser->title; ?></li>
			<li><?php echo $groupedUser->service_a_location; ?></li>
			<li><?php echo $groupedUser->service_a_body; ?></li>
			<li><?php echo $groupedUser->service_b_location; ?></li>
			<li><?php echo $groupedUser->service_b_phone; ?></li>

		<?php endforeach; ?>
	</ul>

Sorry, it is just me thinking aloud, but I was not even sure if it is possible to group them together like that. I was going to have a page for each "section" only displaying that data, but I thought it would be nice to display them all together as an overview for the user.

Link to post
Share on other sites

As a general observation, I think using the page title or page name as a way to connect different pages to a single person is not very robust. It would be better to have a separate section in your page tree for "Persons", with John Doe, Jane Doe, etc, stored under there. Those pages don't necessarily have to appear on the front-end or have a template file. Then other pages are connected to a person by a Page Reference field.

But on to your question...

If it is acceptable to sort the persons listing by the name of the person then you could do this...

$services = $pages->find("template=service-a|service-b, sort=parent.name");
$name = '';
foreach($services as $service) {
    if($service->parent->name !== $name) {
        // This service is from a different person, so output a heading
        echo "<h3>{$service->parent->title}</h3>";
        $name = $service->parent->name;
    }
    echo "<p>$service->title</p>";
}

Note that if you were using a Page Reference field to link services to a person then you would have more sorting options available to you - i.e. you could sort by any field that exists in the person template.

  • Like 1
Link to post
Share on other sites

Thanks robin! I will definitely try this out when I am not on mobile. Unfortunately, the system was set up in a bit of a haste and grew beyond what it was originally intended for. I should have had the foresight and set it up differently. I really appreciate all the help and thank you for always commenting on helpful suggestions/fixes. Hopefully I can get this all working together without a complete overhaul, but it might be needed at this point.

  • Like 1
Link to post
Share on other sites

It works great! I appreciate the help. One thing I noticed (I am sure it is working as expected), I tried wrapping the foreach in a few divs, but the output is a bit strange like so:

<?php
	$people = $pages->find("template=service-a|service-b, sort=parent.name");
	$name = "";
	foreach ($people as $person) {
		$out = "<div class=\"user\">";

		if($person->parent->name !== $name) {
			$out .= "<h3>{$person->parent->title}</h3>";
			$name = $person->parent->name;
		}
		$out .= "<ul>";
		$out .= "
			<li>{$person->title}</li>
			</ul>
			</div>";
		echo $out;
		}
	?>

expected: 

<div class="user">
	<h3>John Doe</h3>
	<ul>
		<li>Service 1</li>
		<li>Service 2</li>
		<li>Service 3</li>
		<li>Service 4</li>
		<li>Service 5</li>
		<li>Service 6</li>
	</ul>
</div>

<div class="user">
	<h3>Jane Doe</h3>
	<ul>
		<li>Service 1</li>
		<li>Service 2</li>
		<li>Service 3</li>
		<li>Service 4</li>
		<li>Service 5</li>
		<li>Service 6</li>
	</ul>
</div>

what actually is occurring:

<div class="user">
	<h3>John Doe</h3>
	<ul>
		<li>Service 1</li>
	</ul>
</div>

<div class="user">
	<ul>
		<li>Service 2</li>
	</ul>
</div>

Did I just miss a tag?

Link to post
Share on other sites
5 hours ago, louisstephens said:

I tried wrapping the foreach in a few divs, but the output is a bit strange like so

You'd need to put more of the markup inside the conditional, otherwise it will be output for each iteration of the foreach.

But for more nested markup like this it will be easier to make sense of if you first loop over all the service pages and build an associative array to group the services by person, then loop over the array.

<?php
$services = $pages->find("template=service-a|service-b, sort=parent.name, sort=sort");
// Group the services by person
$people = [];
foreach($services as $service) {
    $people[$service->parent->title][] = $service;
}
// Take a look at $people using Tracy Debugger just to understand what is going on
bd($people, 'people');
?>
<?php foreach($people as $name => $services): ?>
    <div class="user">
        <h3><?= $name ?></h3>
        <ul>
            <?php foreach($services as $service): ?>
                <li><?= $service->title ?></li>
            <?php endforeach; ?>
        </ul>
    </div>
<?php endforeach; ?>

 

  • Like 2
Link to post
Share on other sites

Ah, thanks robin. The dump in Tracy really helps. I need to use that much more in my set ups for testing. Ill have to play around with the foreach loop, as I tried an if statement (Trying to group sectiona together and section b together),. But hopefully Ill get that worked out.

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.

  • Similar Content

    • By opalepatrick
      I am working on my first Process Module. I am creating forms. Fairly straightforward. However, I really can't work out how to create multiple fieldsets?
      $fieldset = $this->modules->get('InputfieldFieldset'); $fieldset->label = 'Customer Source'; $field = $this->modules->get('InputfieldPage'); $field->inputfield = 'InputfieldSelect'; $field->findPagesSelector = 'parent_id=1449, include=hidden'; $field->labelFieldName = 'yff-lead'; $field->name = 'yfflead'; $field->columnWidth = 16; $fieldset->add($field); $field = $this->modules->get('InputfieldPage'); $field->inputfield = 'InputfieldSelect'; $field->findPagesSelector = 'parent_id=1452, include=hidden'; $field->labelFieldName = 'customer-type'; $field->name = 'customertype'; $field->columnWidth = 16; $fieldset->add($field); //Rinse and Repeat $fieldset->label = 'Contacts'; $field = $this->modules->get('InputfieldPage'); $field->inputfield = 'InputfieldSelect'; $field->findPagesSelector = 'parent_id=1538, include=hidden'; $field->labelFieldName = 'salutation'; $field->name = 'salutation'; $field->columnWidth = 16; $fieldset->add($field); I can create the first fieldset (Customer Source) but then get into trouble as the second fieldset overwrites the first. I understand why, but trying to use the open and close fieldset routine has flummoxed me. Any help appreciated.
    • By VeiJari
      Hello forum, we're trying to use Processwire as our REST-API. We are having problems with our API login to Processwire from frontend. It gives us 403 error.
      We have installed ProcessWire to subdirectory (/api/*) and our frontend is static JS files at root ( / ). Apache access logs gives 404 to our POST-request, but browser devtools shows 403 for our POST /api/login request. 
      Processwire backend panel works. We also have a GET endpoint for the API that returns 200 with correct payload.  So we're wondering why does our GET works but POST doesn't?
      Does this have something to do with Processwire .htaccess, or is this because of our webhost? What should we check first? Any help would be appreciated.
    • By rjgamer
      Hi,
      is there a hook after the current (active) page got created? Or which method got called in the Page class after the Constructor of the current page got initialized?
      Thanks.
       
    • By killedfriendz
      I am very sorry for asking this but i totally do not understand how to set values of checbox using API. 
      I have checbox field on my page with name "order_status". 
      So i've tried few ways to make it checked but it still doesn't work:
       
      $userPage->order_status->value = 1; $userPage->order_status->add(1); $userPage->order_status->add(true); Could you please tell me how to do it?
    • By rjgamer
      Hi guys,
      the field "redirect_last" of type DateTime got not updated. The update on the field "redirect_counter" works and got saved.
      Does anybody know what I did wrong in my code?
      if ($input->urlSegment(1) === 'redirect') { $page->of(false); $page->redirect_last = time(); $page->redirect_counter += 1; if ($page->save('redirect_counter')) { $session->redirect($page->website_url, 302); } } Thanks.
×
×
  • Create New...