Reid Bramblett Posted September 16, 2015 Share Posted September 16, 2015 I am trying to create a list of all the "interest" tags associated with a set of pages. A page can have any number of tags, which are stored in an "interests" field. I can generate a list of all these interests from the requisite pages in a foreach loop, but of course I get all instances of all interests—so if a particular interest tag is on four of the pages, it shows up four times. My code: <ul><?php $kids=$pages->find("template=poi, has_parent=$page"); foreach ($kids as $k) { $ints=$k->interests; $ints->unique(); foreach ($ints as $i) { "<li><a href='interest/$i->name'>$i->title</a></li>"; } } ?> </ul> (I left the "$ints->unique()" line in there—though it is not actually doing anything—because I was convinced it would work. In fact, I played around with jamming "unique()" into more than a dozen places and variations, but perhaps I am misunderstanding that function; I am still a bit shaky on WireArray vs. PageArray.) My most pressing question is: How can I limit the list of results to just one instance of each interest tag. The irony is, I do actually care about how many times an interest tag is used, because on my wish list for this snippet of code is the ability to count that total number, use it to sort the list of interests (by frequency of occurrence), and then also pop it into the list beside each interest title, so the end result would look like this: Interest 1 (20) Interest 2 (16) Interest 3 (12) Interest 4 (8) ... only, you know, with better CSS styling. I've trawled the forum, but none of the solutions to similar situations I found here worked for me, and I poked around the sample blog profile (which has something a bit similar) for inspiration, but to no avail. Any ideas? Thanks. Link to comment Share on other sites More sharing options...
kongondo Posted September 16, 2015 Share Posted September 16, 2015 (edited) You could filter them out in a temporary array...e.g. //example code $interests = $pages->find('template=poi, interests!=""'); //method 1 foreach ($interests as $int) { foreach ($int->interests as $p) {//interests is a multi page field; PW returns them as objects $array1[$p->id] = $p->title;//overwrite duplicate ids in the array key } } //method 2 foreach ($interests as $int) { foreach ($int->interests as $p) { if(in_array($p->id, $array2)) continue;//if we already have that id, skip it $array2[] = $p->id; } } //testing echo '<pre>'; print_r($array1); echo '</pre>'; echo count($array1); echo '<hr>'; echo '<pre>'; print_r($array2); echo '</pre>'; echo count($array2); Above are just examples. You could even store objects in the arrays, or create a temporary WireArray and store them in there.WireArray and PageArray docs: http://processwire.com/api/arrays/ Btw, the above code will not do the counting you want. That's easily doable as well... Edit: Reading your question again, this is probably not what you want...Oh well, code stays though.. Edited September 16, 2015 by kongondo 4 Link to comment Share on other sites More sharing options...
mr-fan Posted September 16, 2015 Share Posted September 16, 2015 If it is a Pagearray you could test before output HTML string with $pageArray->has($page); reference: https://processwire.com/talk/topic/2433-check-if-pagearray-already-contains-a-page/ regards mr-fan 1 Link to comment Share on other sites More sharing options...
Macrura Posted September 16, 2015 Share Posted September 16, 2015 (edited) you have some options... <?php // version using PageArray(); $kids = $pages->find("template=poi, has_parent=$page"); $interests = new PageArray(); foreach ($kids as $k) $interests->import($k->interests); echo '<ul>'; foreach ($interests as $i) { echo "<li><a href='interest/$i->name'>$i->title</a></li>"; } echo '</ul>'; // or find all interests, cycle through but ignore those that don't apply to this page $interests = $pages->find("template=interest"); echo '<ul>'; foreach ($interests as $i) { if(!count($pages->find("template=poi, has_parent=$page, interests=$i"))) continue; echo "<li><a href='interest/$i->name'>$i->title</a></li>"; } echo '</ul>'; ?> wow, 3 replies! Edited September 16, 2015 by Macrura 4 Link to comment Share on other sites More sharing options...
Reid Bramblett Posted September 16, 2015 Author Share Posted September 16, 2015 Thanks for all the speedy replies! Macrura, your first example ends up spewing out even more duplicate hits. Haven't tried troubleshooting that method much yet because I like the backwards logic of !count, but when I try that it throws an error: Parse error: syntax error, unexpected 'continue' (T_CONTINUE) in /Applications/MAMP/htdocs/test-pw/site/templates/_main.php on line 339 Link to comment Share on other sites More sharing options...
Martijn Geerts Posted September 16, 2015 Share Posted September 16, 2015 You need an extra ) before the continue.If you count 3 ('s there should also be 3 )'s 2 Link to comment Share on other sites More sharing options...
Macrura Posted September 16, 2015 Share Posted September 16, 2015 Thanks for all the speedy replies! Macrura, your first example ends up spewing out even more duplicate hits. Haven't tried troubleshooting that method much yet because I like the backwards logic of !count, but when I try that it throws an error: Parse error: syntax error, unexpected 'continue' (T_CONTINUE) in /Applications/MAMP/htdocs/test-pw/site/templates/_main.php on line 339 ok i fixed the code for the 2nd one adding the missing close ) however the first example should work, there can't be duplicate pages in the PageArray(), so you must be doing something funky if you are getting the same 'interest' tag. Are you positive you don't have duplicates in your system - are the interests all stored under the same parent? You should check; if you do have duplicate interest titles in your system PW can't remove the duplicates from the array because it is keyed to the page ID. you could sort the array by title and then check to see if the previous item has the same title and then skip it, that's an easy way to exclude duplicates. Link to comment Share on other sites More sharing options...
Reid Bramblett Posted September 17, 2015 Author Share Posted September 17, 2015 OK, I hereby promise to be better about posting "it don't work!" replies at the end of the day when I'm too tired and rushed to take the debug time to notice a simple thing like a missing close parentheses. (Even as a PHP newbie I should have known this, as I often try to solve such problems by sticking semicolons and/or right curly braces at the ends of random lines of code until the thrown error page goes away, figuring I must have missed one somewhere.) The second code works perfectly now. Thanks all. Link to comment Share on other sites More sharing options...
Reid Bramblett Posted September 17, 2015 Author Share Posted September 17, 2015 Incidentally, @Macrura, your first suggestion is also now working. No idea why it failed yesterday, but the PageArray version is humming along smoothly now. (Each "interest" is, indeed, a unique page stored under an Interests page.) I will definitely use the PageArray version since it will allow me superior sorting options (er, once I figure out how to fiddle with arrays and do the counting part; as I said: PHP noob). Thanks again. 1 Link to comment Share on other sites More sharing options...
Macrura Posted September 17, 2015 Share Posted September 17, 2015 you mean counting like this? $kids = $pages->find("template=poi, has_parent=$page"); $interests = new PageArray(); foreach ($kids as $k) $interests->import($k->interests); $iTotal = count($interests); foreach ($interests as $i) $i->useCount = count($pages->find("interests=$i")); echo "<h3>Interests ($iTotal)</h3>"; echo '<ul>'; foreach ($interests->sort("-useCount") as $i) { echo "<li><a href='interest/$i->name'>$i->title</a> ($i->useCount)</li>"; } echo '</ul>'; 8 Link to comment Share on other sites More sharing options...
Reid Bramblett Posted September 21, 2015 Author Share Posted September 21, 2015 Macrura: Thanks! Works a charm. Link to comment Share on other sites More sharing options...
Macrura Posted September 21, 2015 Share Posted September 21, 2015 cool Link to comment Share on other sites More sharing options...
Recommended Posts
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 accountSign in
Already have an account? Sign in here.
Sign In Now