Soma Posted March 22, 2012 Share Posted March 22, 2012 DOH! Is it becuase 'tags' field is an asmSelect field and not a plain text field or textarea field? Yes! But I'm not getting which one? The one on the articles I guess. Try this: $tagpage = $pages->find("template=tag, name=$tag")->first(); // get the page that is the tag page itself $articles = $pages->find("template=article, tag=$tagpage"); // in case the tag on article is a page reference... you would change the template name to whatever your's are. It's good practice to limit it if you do a $pages->find(). Or better do, if you can, $pages->get("/tags/")->find(...); Link to comment Share on other sites More sharing options...
alan Posted March 22, 2012 Share Posted March 22, 2012 Thanks Soma, I think I may be out of my depth but I'll try to comment and I hope I make sense... I am not using a Template called tag or one called article, so I assume(?) I can delete those parts of the finds (also I changed: tag=$tagpage to tags=$tagpage otherwise I got an error). With these changes I am no longer getting any errors, thank you! But I now see the code does not actually output anything -- I am trying to get out a list of tag names for the page being viewed and while I am getting no errors I'm also not seeing anything. I assume I need to do something with $related_articles, does that sound right so far do you think? Link to comment Share on other sites More sharing options...
apeisa Posted March 22, 2012 Share Posted March 22, 2012 I am trying to get out a list of tag names for the page being viewed foreach($page->tags as $tag) { echo $tag->title; } Link to comment Share on other sites More sharing options...
Soma Posted March 22, 2012 Share Posted March 22, 2012 Alan, my code was just assuming things. Sorry if that confuses you. But your tag pages, uses a template for sure. No way around that. It's just that if you're doing a find over ALL pages in PW to look for a field with the name "mytag", it will not be as fast as if you limit the find to a template or even branch ( or it will possibly even find another page using the same name, thus creating problems) . That's all. It may doesn't matter in a 100 page website, but will with 1million pages. Link to comment Share on other sites More sharing options...
alan Posted March 22, 2012 Share Posted March 22, 2012 @apesia Thank you, so simple it's embarrassing. @Soma NO problem with confusing me, it does me good to stretch my brain! And also I see now how limiting the search is a good idea (important indeed). And previously I didn't see your last line [$pages->get("/tags/")->find(...)] —my bad! I will go and try to implement that. That together with @apesia's note on how to output tags only leaves me needing to work out how to link tags to an 'Other pages sharing this tag' type page. I will try to do that and only post here if I get stuck, er, which might just happen Thanks again! Link to comment Share on other sites More sharing options...
buothz Posted April 22, 2012 Share Posted April 22, 2012 for example i've created related pages for a category, the lenght of a yacht echo '<h3>Yachts Simili</h3>'; //correlati lunghezza $lun = $page->lunghezza; $lunp = $lun+10; $lunm = $lun-10; $yachts = $pages->find('lunghezza>' . $lunm . ',lunghezza<' . $lunp . ', limit=3, sort=lunghezza'); Link to comment Share on other sites More sharing options...
alan Posted April 23, 2012 Share Posted April 23, 2012 @buothz I think my related pages approach is different from yours, in case it's helpful I am going to write it up (eventually) when my site is tidied and up. Meantime, enjoy PW and good luck Link to comment Share on other sites More sharing options...
thomas Posted July 30, 2012 Share Posted July 30, 2012 Hello, I am going to resurrect this old post to share my "related pages" approach. It uses the described pages-as-tags and then looks for pages with the same tags. The more tags are shared, the more "related" the other page is, thus getting it further up on the list. foreach($page->tags as $tags) { $tag = $sanitizer->selectorValue($tags->title); $related_pages = $pages->find("tags.title=$tag"); foreach($related_pages as $related) { if($related->id != $page->id) $related_id[$related->id]++; } } arsort($related_id); foreach($related_id as $key => $val){ $rp = $pages->get($key); ?> <a href="<?=$rp->url;?>"><?=$rp->title;?><br><? } I just translated this to PW from a Perl module I had, so please feel free to correct my PW syntax since I'm new to this. Thanks, thomas 3 Link to comment Share on other sites More sharing options...
alan Posted July 30, 2012 Share Posted July 30, 2012 @thomas Thanks for this, I will take a look and maybe change to this code as my implementation does not have the weighting you've got here. Cheers, -Alan Link to comment Share on other sites More sharing options...
DaveP Posted July 30, 2012 Share Posted July 30, 2012 FWIW, I recently did something similar, but on various fields from $page->siblings with php's similar_text() function (and stopwords). 1 Link to comment Share on other sites More sharing options...
alan Posted July 30, 2012 Share Posted July 30, 2012 Thanks @DaveP, I'll look at those too. Link to comment Share on other sites More sharing options...
apeisa Posted August 30, 2012 Share Posted August 30, 2012 Hello, I am going to resurrect this old post to share my "related pages" approach. It uses the described pages-as-tags and then looks for pages with the same tags. The more tags are shared, the more "related" the other page is, thus getting it further up on the list. foreach($page->tags as $tags) { $tag = $sanitizer->selectorValue($tags->title); $related_pages = $pages->find("tags.title=$tag"); foreach($related_pages as $related) { if($related->id != $page->id) $related_id[$related->id]++; } } arsort($related_id); foreach($related_id as $key => $val){ $rp = $pages->get($key); ?> <a href="<?=$rp->url;?>"><?=$rp->title;?><br><? } I just translated this to PW from a Perl module I had, so please feel free to correct my PW syntax since I'm new to this. Thanks, thomas Thomas, I just today implemented something similar and remembered the logic from your post. Simple and great solution. I made few modifications - most notably I save the related pages into page field also. I also run this code only once per page, since this is part of the import script. Here is how I modified your code: foreach($page->tags as $tag) { $related_pages = $pages->find("template=article, tags=$tag"); foreach($related_pages as $related) { if($related->id != $page->id) $related_id[$related->id]++; } } arsort($related_id); // We limit it to three related pages at max $related_id = array_slice($related_id, 0, 3, true); foreach($related_id as $key => $val){ $rp = $pages->get($key); $page->related_articles->add($rp); } 4 Link to comment Share on other sites More sharing options...
thomas Posted August 31, 2012 Share Posted August 31, 2012 Hi apeisa, that's great. I also played around with this and return a PageArray now. I also tried to use the "weight" as a temporary field in my PageArray so I can sort by weight (like $related->find("sort=weight,sort=-created,limit=3")) but I couldn't get the temporary field to work. $rp = new PageArray(); foreach($related_id as $key => $val) if($tmp++ < $limit) { $rp->add($pages->get($key)); } Does anyone know a way to add a temporary field to each page I add to the PageArray $rp, which I can use to sort after I return $rp? Thanks, thomas Link to comment Share on other sites More sharing options...
apeisa Posted August 31, 2012 Share Posted August 31, 2012 Those should be automatic, like this $page->temp = "hello"; echo $page->temp; Link to comment Share on other sites More sharing options...
thomas Posted August 31, 2012 Share Posted August 31, 2012 Cool apeisa, not sure what went wrong the first time but this works great! Now I've got the next problem (it never stops, does it?) http://processwire.com/talk/topic/1730-find-on-my-own-little-pagearray/ Link to comment Share on other sites More sharing options...
Soma Posted September 1, 2012 Share Posted September 1, 2012 Since this thread is related , I'm also posting this here. I wrote a little helper module to find related pages with score and sorting by score AND modified. Module code can be found here: https://gist.github.com/3558974 $pages->findRelated( Page $page, PageArray $tags, string $field [, string $tmpl, int $limit] ); It add a $pages->findRelated() method. You can do something like this: $found = $pages->findRelated($page, $page->tags, 'tags', 'product|product2', 100); if($found) { foreach( $found->slice(0,5) as $rel ) { echo "<p><a href='$rel->url'>$rel->title</a> ($rel->score)</p>"; } } else { echo "<p>No related Products found</p>"; } 6 Link to comment Share on other sites More sharing options...
ryan Posted September 1, 2012 Share Posted September 1, 2012 Soma, this looks cool, but I'm not sure I fully understand exactly what it does. I've been looking at the code and the function arguments for a bit here, as well as the other thread, and a little confused? Link to comment Share on other sites More sharing options...
Soma Posted September 1, 2012 Share Posted September 1, 2012 Soma, this looks cool, but I'm not sure I fully understand exactly what it does. I've been looking at the code and the function arguments for a bit here, as well as the other thread, and a little confused? What don't you understand? I thought you understand code more than words? I can't explain more without repeating what I already wrote. It does search for pages that have the same tags selected, counts the tags matching and adds that to the score property and sorts by score AND modified, so the most recent are first. $pages->findRelated( Page $page, PageArray $tags, string $field [, string $tmpl, int $limit] ); $page = current page or another one (to exlude it from the search) $tags = a PageArray of tags $field = the Page field which holds the tags, to know which field to search optional: $tmpl = the template of the pages to search in. Multiple templates like "t1|t2|t3" $limit = how many to search It returns a PageArray which can be used further, if none found it returns null. 1 Link to comment Share on other sites More sharing options...
ryan Posted September 2, 2012 Share Posted September 2, 2012 $pages->findRelated( Page $page, PageArray $tags, string $field [, string $tmpl, int $limit] ); $page = current page or another one (to exlude it from the search) $tags = a PageArray of tags $field = the Page field which holds the pages to search optional: $tmpl = the template of the pages to search in. Multiple templates like "t1|t2|t3" $limit = how many to search It returns a PageArray which can be used further, if none found it returns null. Thanks Soma, this clarified it for me. Link to comment Share on other sites More sharing options...
thomas Posted September 3, 2012 Share Posted September 3, 2012 Hi Soma, I just included your module in a page i'm working on, which already has over 400 videos complete with tags imported from the old site. It works great! I only changed the SQL query to "ORDER BY score DESC, modified, ASC" since that makes more sense in my case. Thanks for your work! - thomas Link to comment Share on other sites More sharing options...
Soma Posted September 3, 2012 Share Posted September 3, 2012 Glad it works out for you thomas! Feel free to adapt it to your needs, it's not an official module just a little helper. Link to comment Share on other sites More sharing options...
Michael van Laar Posted November 13, 2012 Share Posted November 13, 2012 Great! Exactly what I was looking for to display related content based on common tags. If I find the time – and if my limited PHP knowledge will be sufficient – I’m going to extend this to be able to find related content based on more than one field. This would also be a great addition to display search results based on their relevance. If there is not yet a solution which does so … Link to comment Share on other sites More sharing options...
DaveP Posted November 13, 2012 Share Posted November 13, 2012 Here's a bit of code that you might find useful. It's something that I referred to earlier in this thread. Say you have a group of pages that represent businesses - like entries in a business directory. Put something like this at the top of your template for each business. <?php $siblings = $page->siblings(); foreach($siblings as &$sibling){ $pagetext = strtolower($page->title.' '.$page->city.' '.$page->postcode); $siblingtext = strtolower($sibling->title.' '.$sibling->city.' '.$sibling->postcode); $stopwords = array('limited','shop','emporium'); $pagetext = str_replace($stopwords,'',$pagetext); $siblingtext = str_replace($stopwords,'',$siblingtext); similar_text($pagetext, $siblingtext, $sim); $sibling->similarity = $sim; } $siblings->sort('-similarity'); ?> $stopwords are words you want to be ignored in the comparison (in my real-world use they are business-specific terms that a great many businesses have in their names). Then to display a list of similar entries... <?php $score = 40; if($siblings->eq(1)->similarity >= $score){ echo '<h3>Similar Entries</h3>'; echo '<ul>'; for($i = 1;$i <= 10;$i++){ if($siblings->eq($i)->similarity < $score) continue; echo "<li><a href='{$siblings->eq($i)->url}' title='{$siblings->eq($i)->title}, {$siblings->eq($i)->address}, {$siblings->eq($i)->city} {$siblings->eq($i)->postcode}'>{$siblings->eq($i)->title}</a>"; if($user->isSuperuser()) echo ' '.round($siblings->eq($i)->similarity, 2); echo "</li>"; } echo '</ul>'; } ?> Adjust $score to get satisfactory results. (And the bonus prize is that logged-in super users get to see the score in the page output.) 2 Link to comment Share on other sites More sharing options...
antknight Posted March 18, 2014 Share Posted March 18, 2014 Hi guys, Sorry to drag up an old thread but this is probably the best place for it. I have implemented Thomas' code but I need to put a limit on the number of pages returned as I only have space for 4 in my markup. I have tried putting the limit selector in various places but I always get an error. Thanks Anthony Hello,I am going to resurrect this old post to share my "related pages" approach. It uses the described pages-as-tags and then looks for pages with the same tags. The more tags are shared, the more "related" the other page is, thus getting it further up on the list. foreach($page->tags as $tags) { $tag = $sanitizer->selectorValue($tags->title); $related_pages = $pages->find("tags.title=$tag"); foreach($related_pages as $related) { if($related->id != $page->id) $related_id[$related->id]++; } } arsort($related_id); foreach($related_id as $key => $val){ $rp = $pages->get($key); ?> <a href="<?=$rp->url;?>"><?=$rp->title;?><br><? } I just translated this to PW from a Perl module I had, so please feel free to correct my PW syntax since I'm new to this.Thanks,thomas Link to comment Share on other sites More sharing options...
DaveP Posted March 18, 2014 Share Posted March 18, 2014 Anthony, have you tried $related_pages = $pages->find("tags.title=$tag,limit=4"); 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