Jump to content
ptjedi

Selectors: Get architects from city buildings

Recommended Posts

Hello everyone,

I am struggling here with a problem for I wish there is a more elegant solution. Picking up the Skyscrapers demo example, if I wanted to list all architects that had any kind of participation on a specific city, what would be the correct process?

I can always list all buildings, pick up their architects, store them in a variable and get rid of duplicates, but I am pretty sure PW has a more interesting approach to the problem. Can anyone help me out on this one?

Thanks!

Share this post


Link to post
Share on other sites
I can always list all buildings, pick up their architects, store them in a variable and get rid of duplicates, but I am pretty sure PW has a more interesting approach to the problem. Can anyone help me out on this one?

If we're using the skyscrapers example literally, like the demo site, then there is no structural connection between cities and architects since they are in different branches, not part of the same family:

/architects/

/cities/

So the only connection of an architect to a city is via a page reference field on a building. That means that somewhere, the process you described has to take place, like this:

$architects = new PageArray();
foreach($page->children as $building) {
 $architects->add($building->architects);
}
$architects->sort('title');
echo $architects->render();

On the individual architect pages, if you wanted to list the cities they are active in, you could do this:

$buildings = $pages->find("architects=$page");
$cities = new PageArray();
foreach($buildings as $building) {
 $cities->add($building->parent);
}
$cities->sort('title');
echo $cities->render();

In either case, you don't need to worry about duplicate removal is ProcessWire is already taking care of that for you.

Share this post


Link to post
Share on other sites

Never realised about duplicate removal - I can go and trim some code back on a few sites. Thanks Ryan :)

Share this post


Link to post
Share on other sites

Thank you Ryan for your quick assistance. I've tried to reproduce what you suggest but with little success. My own example is similar to the Skyscrapper one that I mentioned, but I think it's better to explain everything from bottom-up:

This is a catalog that has 2 types of entities (templates): products and attributes. Both are pages (of course) and I have Dropdown menus inside products that let me choose from the attributes created outside the tree of pages. My tree looks like this:

  • Home
  • Page 1
  • Page 2
  • Catalog
    • Products
      • Product 1
      • Product 2
      • Product 3
      • ...

      [*]Types

      • Type Attribute 1
      • Type Attribute 2
      • ...

      [*]Areas

      • Area Attribute 1
      • Area Attribute 2
      • ...

So, for each product I can associate with a Type and multiple Areas.

What I need is: given the Area, list all Types that are selected inside that area's products. This, inside a page OUTSIDE the catalog, so I need to point everything in there.

Here's the code I am using:

$area = $pages->get("/catalog/area/")->find("title*=Hospital"); // gets page that contains "Hospital" in title (will return only one)

$products = $pages->get("/catalog/products/")->find("catalog_product_area=$area"); // lists all products that matches that attribute

$types = new PageArray();
foreach($products as $product) {
   $types->add($product->parent);
}
$types->sort('title');
echo $types->render();

The result shows the following:

Produtos
1
2
3
4
5
6
7
Next

Any idea?

Share this post


Link to post
Share on other sites

Not sure what exactly you need. Those numbers with the "next" looks like a pager? Is that coming from where? The $types->render() causes it? However this is not what you need, you just have to foreach the types and output them any way you like.

$types = new PageArray();
foreach($products as $product) {
 // get the types selected, assuming your page field is "catalog_product_type"
 // add() will import a set of page array or a single as of latest PW, if older PW you can
 // use import() method to import arrays
 $types->add($product->catalog_product_type);
}
echo "<ul>";
foreach($types->sort('title') as $type) {
 echo "<li>$type->title, $type->url, $type->id</li>";
}
echo "</ul>";
  • Like 1

Share this post


Link to post
Share on other sites

That is exactly what I needed Soma, many thanks. And thank you for the comments as well. As a newbie I find them precious.

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.

  • Similar Content

    • By Anders
      I want to allow full text search on my site. There is a very nice solution that comes right out of the box:
      $selector = "title|body~=$q, limit=50"; This works, but to make it even better I would want to give higher weight to pages where the search term occurs in the title, than if it just occurs in the body. After all, a page with the title "Wine from France" is probably the best match for the search "france wine". How do I accomplish this in ProcessWire?
      I can see three possible paths, but I am not very fond of any of them:
      Do a direct SQL query, circumventing the API, along these lines. But I would prefer to abstract away the database layout if at all possible. Use something like ElasticSearch, but to be honest that would be to complicated to set up and maintain in the long run. Make multiple lookups, first for matches in the title, then for matches in the body, and merge and sort in PHP. My suspicion is that this would get complicated quite quickly. For instance, how do you deal with a page that has two of the three search terms in the title and the third in the body? Is there a magic option four I should look into? Or are any of the above options better than the others? Any input is welcome!
    • By iipa
      Hi!
      I have two Page Reference fields: Category and Subcategory. Category is parent of Subcategory, and can have 0 to n Subcategories. Fields are selected by dropdown selection.
      I'm trying to achieve following logic:
      1. Select Category (obviously works)
      2. Change Subcategory options based on selected Category (this works)
      3. Hide the Subcategory field if Category has no Subcategories (to prevent weird dropdown with nothing to select)
      I have tried to investigate two possible alternatives to achieve step 3:
      A) Make dynamic condition into Subcategory selection's "Only visible if..." field
      B) Make a hook that fires when Category changes, then hides Subcategory field if Category has no children
      So far I haven't been successful in either. Conditions I've tried always lead to hidden field, and I haven't been able to find set up a hook that fires on field change.
      So here's the question (finally): Is there a way to alter field visibility in API, for example in ready.php or inside a hook? In API I could loop through categories, find the ones that have children and then make a selector based on their IDs.
    • By schwarzdesign
      I'm working on a news feed that will show the most recent news in a full teaser grid, and all older news as a simpler archive-type list view. My selectors so far:
      $news_full = $page->children("template=news, limit={$page->feed_count_full}"); $news_archive = $page->children("template=news, start={$page->feed_count_full}, limit=9999"); The $page->feed_count_full field controls how many items to show in the teaser grid (I've confirmed it contains the correct value, and the $news_full selector works as intended).
      This works, but I don't like the limit in the second selector. Unfortunately, if I leave it out (i.e. I only specify a start, not a limit), the start is ignored and I get all news instead. Not a big problem as we will never have more than 9999 news, but it still bothers me, as semantically speaking I don't want to set a limit in this case.
      Is this the intended behaviour of start/limit selectors? Is there a cleaner way to specify an offset (start selector) without a limit?
      ProcessWire Version 3.0.123
      Thanks!
    • By pwFoo
      I played with the Selectors object and would like to use it for a special use case...
      That is a custom Selectors object with dummy data converted to an php array to see the structure (Selectors object is a WireArray with "fields" added)
      Array ( [0] => Array ( [0] => Array ( [field] => seg1 [value] => val1 [not] => [group] => [quote] => [forceMatch] => ) [1] => Array ( [field] => seg2 [value] => val2 [not] => [group] => [quote] => [forceMatch] => ) ) )  
      But instead of "seg1" the field name is "field" with value "seg1" (= my field name).
       
      So I can't search the Selectors WireArray (= custom WireArray with added Selectors objects) with PW "find('seg1=val1')", Is there a way to search with "find()" or build a simple wrapper to make the elements searchable / filterable with find()?
    • By Peter Knight
      <?php $Cats=$pages->find("parent=1086, id!=$page, sort=sort"); foreach($Cats as $Cat) { echo " I have a selector that pulls in 4 child pages of a parent and the order is set to reflect the order of the tree.
      My client has asked that instead of
      Cat 1 | Cat 2 | Cat 3 | Cat 4
      we instead display
      Cat 4 | Cat 1 | Cat 2 | Cat 3 
      However, I can't change the sort order in the tree.
      Can anyone guide me on the correct approach here?
      Thanks
       
×
×
  • Create New...