Search the Community
Showing results for tags 'sort'.
-
Find Merge Adds a Pages::findMerge() method that allows multiple PageFinder selectors to be merged into an efficient paginated set of results. This can be useful when you need more sophisticated sorting of results than what would be possible using only the sort value in a single $pages->find(). Details $results = $pages->findMerge($selectors, $options); $selectors is required and must be an array of selectors. Each selector can be in string format or array format. The findMerge() method will loop over the selectors in the order supplied, adding matching pages to the final results. $options is an optional associative array of options. limit (int) Limit for pagination. start (int) Manually override the start value rather than have it be automatically calculated from the current page number. excludeExisting (bool) Whether or not to exclude pages in each selector that have already been matched by a previous selector. Default is true. keepFirst (bool) When excludeExisting is false then a page might match more than one selector in the supplied array. But each page can only appear once in the results and if keepFirst is true then the page will appear in its earliest position in the results, whereas if keepFirst is false it will appear in its latest position in the results. Default is true. As a shortcut you can supply an integer as the second argument and it will be treated as the limit for pagination. Basic usage For most use cases only a limit will be needed for the $options argument. $selectors = [ 'title%=yellow', // title contains "yellow" 'title^=z', // title starts with "z" 'title=elephant', // title equals "elephant" 'template=colour, sort=-title, limit=3', // 3 colours in reverse alphabetical order 'template=country, sort=title, limit=40', // 40 countries in alphabetical order ]; $results = $pages->findMerge($selectors, 10); if($results->count) { echo "<p>Showing results {$results->getPaginationString()}</p>"; echo "<ul>"; foreach($results as $result) { echo "<li><a href='$result->url'>$result->title</a></li>"; } echo "</ul>"; echo $results->renderPager(); } Advanced usage The following notes are only relevant to rare cases and most users can safely skip this section. In the demo example the colour page Yellow will potentially match both the 1st selector and the 4th selector. Because of this the excludeExisting and keepFirst options will have an effect on the results. excludeExisting option false Note that the 4th selector asks for 3 colour pages (limit=3). By default excludeExisting is true, which means that when the 4th selector is processed it is interpreted as saying "find 3 colour pages in reverse alphabetical order that have not already been matched in an earlier selector". We can see that there are 3 pages in the results from that selector: Violet, Red, Orange. But if excludeExisting is set to false then the results are different. The matches of the 1st selector (Yellow, Yellow Warbler) are not excluded from consideration by the 4th selector (the 4th selector matches will be Yellow, Violet, Red), and because each page can only appear once in the results this means that the 4th selector ends up only adding 2 more pages to the results. $selectors = [ 'title%=yellow', // title contains "yellow" 'title^=z', // title starts with "z" 'title=elephant', // title equals "elephant" 'template=colour, sort=-title, limit=3', // 3 colours in reverse alphabetical order 'template=country, sort=title, limit=40', // 40 countries in alphabetical order ]; $options = [ 'limit' => 10, 'excludeExisting' => false, ]; $results = $pages->findMerge($selectors, $options); keepFirst option false As described above, the Yellow page potentially matches both the 1st and 4th selector. By default Yellow will appear in its earliest position within the results, i.e. the position resulting from it being matched by the 1st selector. But if keepFirst is set to false (and excludeExisting is false) then it will appear in its latest position within the results, i.e. the position resulting from it being matched by the 4th selector. $selectors = [ 'title%=yellow', // title contains "yellow" 'title^=z', // title starts with "z" 'title=elephant', // title equals "elephant" 'template=colour, sort=-title, limit=3', // 3 colours in reverse alphabetical order 'template=country, sort=title, limit=40', // 40 countries in alphabetical order ]; $options = [ 'limit' => 10, 'excludeExisting' => false, 'keepFirst' => false, ]; $results = $pages->findMerge($selectors, $options); keepFirst has no effect when excludeExisting is true. https://github.com/Toutouwai/FindMerge https://processwire.com/modules/find-merge/
-
Hello, I have a separate sort dropdown and filter section. This is very similar to the processwire demo - https://demo.processwire.com/search/?sort=parent.name I also have the same "issue" if you would call it that where i can sort or I can filter, but I can not do both. This is because the url changes. So a sort URL may look like: website.com/subpage/?sort=random and a filter like: website.com/subpage/?placement=x&channel=y_z I'm looking to be able to sort and filter. So if I change the sort, it won't remove the current filter and vice versa. I have the sort dropdown running off one bit of JS and the filter on another with examples of both below: This is sort JS $(document).ready(function() { $(".sort-select").on("change", function() { document.location.href = location.pathname+"?sort="+$(this).val(); //console.log(location.pathname+"?sort="+$(this).val()) //console.log(location.search) }); }); This is filter JS document.querySelector("form").onsubmit=ev=>{ ev.preventDefault(); let o={}; let noPage = window.location.pathname.split("/").slice(0,-2).join("/") + "/"; ev.target.querySelectorAll("[name]:checked").forEach(el=>{ (o[el.name]=o[el.name]||[]).push(el.value)}) if(noPage.length > 1){ document.location.href = noPage+"?"+Object.entries(o).map(([v,f])=>v+"="+f.join("_")).join("&"); }else{ document.location.href = location.pathname+"?"+Object.entries(o).map(([v,f])=>v+"="+f.join("_")).join("&"); } } This is my input build within the func.php doc: $selector = ''; // Get the inputs, sanitize and whitelist. Then create an array, then replace _ for | in array for selector filter. Output selector if($input->get->sort){ $sorted = $input->get->text('sort'); $input->whitelist('sort', $sorted); //$selector = $selector .= ",sort=$sorted"; } if($input->get->channel){ $channel = $input->get->text('channel'); $input->whitelist('channel', $channel); $chanArray = explode("_", $channel); $chan = $channel = str_replace('_', '|', $channel); $selector = $selector .= ",ab_channels=$chan"; } if($input->get->content){ $content = $input->get->text('content'); $input->whitelist('content', $content); $contArray = explode("_", $content); $cont = $content = str_replace('_', '|', $content); $selector = $selector .= ",ab_content=$cont"; } if($input->get->brand){ $brands = $input->get->text('brand'); $input->whitelist('brand', $brands); $brandArray = explode("_", $brands); $brand = $brands = str_replace('_', '|', $brands); $selector = $selector .= ",ab_brand=$brand"; } if($input->get->style){ $styles = $input->get->text('style'); $input->whitelist('style', $styles); $styleArray = explode("_", $styles); $style = $styles = str_replace('_', '|', $styles); $selector = $selector .= ",ab_creative_style=$style"; } if($input->get->ugc){ $ugcs = $input->get->text('ugc'); $input->whitelist('ugc', $ugcs); $ugcArray = explode("_", $ugcs); $ugc = $ugcs = str_replace('_', '|', $ugcs); $selector = $selector .= ",ab_influencer=$ugc"; } if($input->get->place){ $placement = $input->get->text('place'); $input->whitelist('place', $placement); $placeArray = explode("_", $placement); $place = $placement = str_replace('_', '|', $placement); $selector = $selector .= ",ab_placement=$place"; } if($page->template == 'adbank_brand_page'){ $brand = $page->title; $selector = $selector .= ",adbank_brands=$brand"; } $selector = "template='adbank_pages',limit=12,sort={$sorted} " . trim($selector, ", "); Any direction on how to combine these would be really appreciate. I know AJAX may be the best route overall but I don't know how to action that and for time sake trying to get these to both work with page refresh feels more accessible... TIA
-
Repeater Easy Sort Adds a compact "easy-sort" mode to Repeater and Repeater Matrix, making those fields easier to sort when there are a large number of items. The module also enhances Repeater Matrix by allowing a colour to be set for each matrix type. This colour is used in the item headers and in the "add new" links, to help visually distinguish different matrix types in the inputfield. Screencasts A Repeater field A Repeater Matrix field with custom header colours Easy-sort mode There are two ways to enter easy-sort mode. 1. Click the double-arrow in a Repeater item header. This activates easy-sort mode and also highlights the item with a black background so it's easier to find it in easy-sort mode. 2. Click the horizontal ellipsis icon in the Repeater field header to activate easy-sort mode. To return to normal mode click the vertical ellipsis icon. While in easy-sort mode: The items will reduce in width so that more items can be shown on the screen at once. The minimum width is configurable in the field settings. Any items that were in an open state are collapsed, but when you exit easy-sort mode the previously open items will be reopened. You can drag an item left/right/up/down to sort it within the items. You can click an item header to open the item. An "Exit easy-sort mode" button appears at the bottom of the inputfield. Configuration In the field settings for Repeater and Repeater Matrix fields you can define a minimum width in pixels for items in easy-sort mode. While in easy-sort mode the items will be sized to neatly fill the available width on any screen size but will never be narrower than the width you set here. If desired you can enable easy-sort mode for a field by default. Since easy-sort is then the default mode for the field no "Exit easy-sort mode" button is shown. Use the mode buttons in the field header to change between easy-sort and normal mode when needed. In the field settings for Repeater Matrix you can define a custom header colour for each matrix type using an HTML "color" type input. The default colour for this type of input is black, so when black is selected in the input it means that no custom colour will be applied to the header. Exclusions The easy-sort mode is only possible on Repeater/Matrix fields that do not use the "item depth" option. https://github.com/Toutouwai/RepeaterEasySort https://processwire.com/modules/repeater-easy-sort/
- 10 replies
-
- 16
-
How might I programmatically output images from an Image field from another template in descending order? I want to reverse the order of images on the front-end page (see code below). I want to keep the order in ProcessWire Admin. The Image field accepts multiple images. Code: foreach ($page->children() as $p) { if( isset($p->foo->id) && $pages->get($p->foo->id)->images->count>0 ) { foreach ($pages->get($p->foo->id)->images as $img) { echo "<img data-src=\"{$img->width(140)->url}\" width=\"\" height=\"\" alt=\"{$p->foo->title}\" class=\"uk-align-right uk-visible@m\" uk-img>"; } } } Things I tried (that didn't have an effect): $pages->get($p->foo->id)->images->sort("sort=-sort") $pages->get("id={$p->foo->id},sort=-sort")->images I also wanted to try a for() loop but didn't know how to.. # Failed attempts: $pages->get($p->foo->id)->images[0]; $pages->get($p->foo->id)->images->1; # This works - but only for first and last (not a third image) and I would need to check if each image existed. $pages->get($p->foo->id)->images->first; $pages->get($p->foo->id)->images->last; I am aware that ProcessWire isn't specifically designed for working with child pages this way - it's probably even a bad practice - it's just that it almost always works very, very well. ? PS: Would you normally set the width and height attributes, or leave them out?
- 2 replies
-
- image field
- template
-
(and 2 more)
Tagged with:
-
Hello all, My page has a lot of images. I created a gallery_image field to upload and display them. Unfortunately they are sort of unordered in the backend, though the filenames are numbered sequentially. I understand that this reflects the order of finished uploads. I figured out how to sort them on the frontend, but is there a way to do the same in backend? I guess this HookAfterPagesSave.module found here https://processwire-recipes.com/recipes/extending-page-save-process/ might do the trick but I'm too new to processwire and too unexperienced in coding to see what code to write. Anyone can help? Thanks in advance Hanna
-
First the structure (offtopic, Structure reminds me of EE ) Home -Company Page --Section (template: container) ---Child page 1 (template: content) ---Child page 2 (template: content) ---etc. I have editors that can add pages to template container, but not edit the page. Problem is that they can not sort the child pages (template:content) by default. Solved it by adding a 'move-children' role that has move-pages and sort-pages permissions. The problem lies in setting that role and permissions to the template 'container'. You cannot select the 'Create Pages' checkbox for role 'move-children' unless you also give the 'move-children' role the 'edit-page' permission. (It's disabled) (I'm not sure if I'm using the correct terms...) Eventually I solved it by setting the 'edit-pages' permission to the 'move-children' role, checking all the boxes for the template access, and then removing the 'edit-pages' permission. I don't know if this is the intented behaviour but I thought I'd share it with you to see what you've experienced. Thanks
- 2 replies
-
- 1
-
- sort
- permissions
-
(and 2 more)
Tagged with:
-
Hi, trying to order pages by modified date, date. I can do 'sort=-date_modified, sort=-date' but that will always put the modified date first regardless of actual date order. I just want to coalesce the two fields and sort. Any ideas would be appreciated.
-
I'm having trouble with sorting by repeater count. We have awards given to each work and the awards are in a repeater. Doing "sort=-awards.count" However it isn't working. Anyone got any ideas?
-
Hello, i need to sort $pages by the first letter an show on the page like A - Aname Page - Aname Page - Aname Page - Aname Page B - Bname Page - Bname Page - Bname Page - Bname Page How can i check which is the first letter from the page.title ?? Tnx
-
What's the easiest way to retrieve a PageArray -- with an offset and a limit, for use in paginated search results -- that is sorted by title using PHP's SORT_NATURAL instead of alphabetically? I was hoping there was a config setting or API method that would handle it for me, but if there is, I haven't stumbled across it yet.
-
I have done a bit of searching, but I can not seem to find an actual answer. I have a list of services as child pages under "Services". I can output the services just fine, but I cant wrap my head around how to group them "alphabetically" like: Services A - Service "A" 1 - Service "A" 2 - Service "A" 3 B - Service "B" 1 - Service "B" 2 - Service "B" 3 C - Service "C" 1 - Service "C" 2 - Service "C" 3 Has anyone achieved this type of functionality before?
-
Hi all! I have a little problem here. I want to sort a list of addresses by streetname and then by number. First, I just had a field "prod_objekt" (address) containing both and then have a foreach loop like this: $pages->get('/produzenten/')->prod_repeater->sort('prod_objekt') as $produzent. Unfortunately, this would not sort by streetnumber if I had the same streetname but multiple numbers. Now, I thought I could sort by two fields. prod_object (adress) first and then by prod_hausnummer (streetnumber). But I just don't know the code for it. I tried this: $pages->get('/produzenten/')->prod_repeater->sort('prod_objekt.prod_hausnummer') as $produzent, but it wouldn't work. Any ideas on how to solve this? Thanks for your help Roli
-
Hello, I'm facing an issue with my page fieldtype. Pages appear in the order they were created although I'd like to see them sorted in alphabetical order (by title). The pages are well-sorted in my tree, but in that particular Page fieldtype (on another page), I can't find any place where I would decide on what field I can sort them. Am I missing something here ? Let me know if I'm not clear enough in my explanations. Thanks in advance for a clue
-
This is a pretty typical thing. Open a page, it does a $pages query, finds 112 things and I list them on the page. There is pagination too, 20 per page. I want a sort dropdown box so the visitor can change alpha sort or whatever other sorts and filters I eventually use. My first thought is to just refresh the page with a url query like "page/?sort=az" and then adjust the query in the template code. But to do this, it will require a page refresh, which means the sort box goes back to its default, and not sure how it effects pagination. If I do a page refresh, I'll have to keep the sort settings in the session or something, to make sure I always apply correct sort on page load. But at the same time, I've already got the $pages array, it would be much nicer to shuffle it and update the page without a page refresh, rather than run the query over and over again. But then again, the pagination buttons already cause page refreshes, so that is already happening anyway, unless I convert the pagination buttons to also be no-refresh somehow. I figure this is a very common problem, to paginate results and give users a sorting/filtering option. What is the common methods for handling it? Session, url query, ajax? If I just add the sort to the url query, how do I make that work in the pagination links?
-
I need to sort results by title ascending, and title includes special characters (croatian letters). The problem is that results are sorted but not 100% correct: e.g. $authors = $pages->find("template=author,sort=title"); Cavali Cavilon Čavlović Cesare ... You see intruder (bolded), it looks like sort engine treats letters C and Č as same ones. I'm not sure that this is Processwire related, but maybe API has solution for this kind of behavior? I have UTF-8 page content type .
-
Hi all! I want to sort child-pages by two fields but I don't know if it is possible within one selector or if I have to make two separate queries <?php foreach ($page->children('sort=checkbox, sort=-number') as $child): ?> I want to keep 'checked' pages on top and sort them and all following by the 'number' field. The 'checkbox' field is a
-
I use pagination modul. I have a field which has born year info. But I put the years with sign "-" for BC (Before Christ). my selector sorts like as text. -384, -4, -412 .. it must be: -412, -384, -4 selector: $pages=$page->children("limit=60, sort=date_field"); I want to order my pages like as php natsort function. thank you.
- 5 replies
-
- pagination
- selector
-
(and 1 more)
Tagged with:
-
Dumb question coming up. I can't get sorting to work. I show child pages (posts) of a parent page (news) on the homepage with this in the template: $news = $pages->find("template=post"); foreach($news as $post) { ... Sort order setting in the template or page is apparently ignored. The sort order is correct in the admin area, but shows up wrong on the home page. What am I missing?
-
Hi! I've got a page with text area where user can check some codes divided by space, semicolon or comma. I can use two solutions to search for these codes: First method: $prCodesArray = preg_split('/[\\s,;]+/', $prCodes, -1); $selector = "title=" . implode("|", $prCodesArray) . ", template=pr-code, include=all, limit=100"; $prCodePages = $pages->find($selector); $prCodeCount = count($prCodePages); if ($prCodeCount) { foreach ($prCodePages as $prCodePage) { $content .= $prCodePage->title . " - " . "<span title=\"". $prCodePage->parent->pr_code_group_description . "\">" . $prCodePage->parent->title . "</span> - " . $prCodePage->pr_code_description . "<br>"; } } else { $content .= $prCode . __(' - Not found.') . "<br>"; } Advantages: + it's fast ~0.21s for ~40 codes. Disadvantages: - alphabetical results sorting while I want input order, - doesn't show not found codes. Second method: $prCodesArray = preg_split('/[\\s,;]+/', $prCodes, -1); foreach ($prCodesArray as $prCode){ $selector = "title={$prCode}, template=pr-code, include=all, limit=10"; $prCodePages = $pages->find($selector); $prCodeCount = count($prCodePages); if ($prCodeCount) { foreach ($prCodePages as $prCodePage) { $content .= $prCodePage->title . " - " . "<span title=\"". $prCodePage->parent->pr_code_group_description . "\">" . $prCodePage->parent->title . "</span> - " . $prCodePage->pr_code_description . "<br>"; } else { $content .= $prCode . __(' - Not found.') . "<br>"; } } } Advantages: + sorting like input order, + shows not found codes. Disadvantages: - it's slow as hell ~2.5s for ~40 codes. Is there any solution to join advantages of both methods? Also, as you can see I have to use include=all statement in my find methods and I don't know why. I've used Import Pages from CSV module. All codes (pages) are published and there is no access control on any of them.
-
This must be simple, however, I couldn't figure out how to do it. I got this structure in the admin tree: Page 1 [Template A] Children 1-1 [Template B] Children 1-2 [Template B] Children 1-3 [Template B] ... Page 2 [Template A] Children 2-1 [Template B] Children 2-2 [Template B] ... Page 3 [Template A] Children 3-1 [Template B] ... What I want in the front end, is this sort order: Children 1-1 Children 1-2 Children 1-3 Children 2-1 Children 2-2 Children 3-1 Plus, the order should depend on the order in the admin tree. So, if I move Page 3 on top of the tree, the children of Page 3 should appear first. I tried this, but the order seemed to be random (without a connection to the order in the admin tree): $pages->find("template=B, sort=sort"); I also tried this, and again I got a random looking order: $pages->find("root.template=A, sort=sort"); Do you have any idea? Thanks, Nils
-
Hi, I'm sorry if this has been adressed before but I couldn't find anything about it. I'm pretty new to processwire but not to php or object developpment. I'm working on a blog and the request was to add a custom date field on articles that allows the user to override the "date" associated to the article. It's basically a publish date. If set, that date is used to sort the article and also if the date is in the future the article will not be displayed on the website. Here is the selector I used to sort my articles list before: $pages->find('template=news, sort=-created, limit=4'); and here is how I do it now : $pages->find('template=news,!news_date>today, sort=-created|-news_date, limit=4'); The only issue is that the sort does not sort a big mashup of all the dates regardless of whether it's in "created" or "news_date" but it sorts one and then the other. So what I get is a list of dates like this 02 jul 2015 (news_date) 15 Jul 2014 (news_date) 2 Dec 2014 (created) 1 Nov 2014 (created) The news_date list is on top of the created list. Do you know how I could achieve this? Thanks a lot
-
hi. i have a selector like this: $result = wire('pages')->find("template=xx, field_x=439|417|456|402"); now i need the $result sorted exactly like the values are commited in field_x. How to do this? thanks, martin
-
I have a PageTable field that is updated via a custom module. Pages are updated by deleting them then re-adding but crucially need be re-added in the same order in the PageTable field. If I re-add pages, they go to the bottom of the field (it's a manual drag n drop setting). Is there a way to re-add where the page was previously? Or at the very least I need to maintain the first page in the field. It has a checkbox ticked if it's first so the re-added page could use that to test whether it needs to go first. I just don't know how to set the order of pages in a PageTable field via the api. Any help here much appreciated.
-
Hello, on a brandnew 3.0.35 install, I get wrong results for $page->sort. My structure is like Home -level1-1 -level2-1 -level2-2 -level2-3 -level1-2 -level1-3 When I do foreach($homepage->children as $child) { echo $child->sort; } It gives me: 3, 4, 5 where it should be 0, 1, 2. When I loop through the children's children, the values are correct foreach($homepage->children as $child) { foreach($child->children as $ch) { echo $ch->sort; } } returns 0, 1, 2. On level1 there never where more than 3 pages. So I don't know why it possibly could be starting with 3 instead of 0. Is there any way to recreate the sort index? I tried moving level1 pages around in admin but that didn't change anything. EDIT: I also tried $homepage->children('sort=sort'). Same results.