Jump to content

Robin S

Members
  • Posts

    4,928
  • Joined

  • Days Won

    321

Everything posted by Robin S

  1. Yes, that's exactly what it does. It works through the supplied selectors in order and appends the results of each to the last (with the provisos covered in the readme) but the returned PageArray is efficiently paginated which is important for performance if you are dealing with large numbers of results. In your case you are only retrieving 20 results which you're not paginating so you don't need this module for that scenario.
  2. This new module can also be useful for these kinds of cases: It doesn't actually use the "id.sort" feature but will give the same kind of result in a similarly efficient way.
  3. 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/
  4. The setting is now called "Page containing default/fallback value for this field"
  5. Thanks for the report @monollonom, should be fixed in v0.2.4
  6. Maybe it's not intuitive but an equals sign matches pages in a Page Reference field regardless of whether it is a "single page" field or a "multiple pages" field with more than one page selected in it. So it must be some other issue, like maybe your page you are trying to find is unpublished or hidden?
  7. You just need a plain equals sign. $pages->find("template=adebate, deb_inter=$page->id"); And usually I just use $page alone because the string value of a Page object is its ID. $pages->find("template=adebate, deb_inter=$page");
  8. In recent PW versions it's possible to insert new repeater items at any position, so if your customer wants to insert an item at the top they can click the "Insert new item before this one" button on the first repeater item. See the video at the top of this blog post: https://processwire.com/blog/posts/new-repeater-and-repeater-matrix-features/ Though I'm not sure why new repeater items added this way are not expanded when they are added, so I've opened a GitHub issue about it: https://github.com/processwire/processwire-issues/issues/1596
  9. If you are adding the class in a hook rather than in an inputfield you are creating then the likely reason is that your hook is firing too late, after this module has already done its work. You would need to hook at the renderReady state and may need to adjust your hook priority to be sure of adding the class in advance of this module. Remember that this module also provides a hookable method allowing you to disable the module for specific inputfields - see the Usage section in the readme.
  10. Probably the first step of "Add module"... ...should be updated to include any rules about how the repo needs to be organised. @ryan But most modules that I've seen abide by the following principles, so that's probably a good way to go: 1. Name the repo the same as the module, in your case "ProcessIndieAuth". 2. Put the module files and readme in the top level of the repo. Includes or assets could go in subfolders when needed.
  11. @GradDev, I think it would be useful to have a setting to determine if duplicate items are unset or skipped when adding to a WireArray/PageArray, so I opened a request for Ryan to consider: https://github.com/processwire/processwire-requests/issues/447
  12. Hi @GradDev, The $pageData = $pageData->unique() line is redundant because WireArrays/PageArrays never contain duplicates unless you specifically allow them using setDuplicateChecking(false). I can't reproduce the issue here - the order of items in a PageArray is the same as the order I add them in and they are not ordered by ID. In my example I am adding countries: But you can see that when adding an item that already exists in the PageArray, the earlier item is removed - Finland, Iceland and Ireland are added in the last append() but would already exist in the PageArray. If you wanted pre-existing items to maintain their earlier position in the PageArray you could modify the selectors so that items in the PageArray are excluded:
  13. It sounds like output formatting is off for the page in question. I haven't used multi-instance so I'm not sure if it's normal for pages retrieved this way to have output formatting off by default or if it's a bug. But you can turn output formatting on for your page like this: // $p is your page from the other instance $p->of(true); // Now output field values from $p
  14. The labels are settings/properties of InputfieldSelectImages so you would need to customise them there rather than via FieldtypeDynamicOptions. You'd use a hook like this: $wire->addHookAfter('InputfieldSelectImages::renderReadyHook', function(HookEvent $event) { $inputfield = $event->object; $field = $inputfield->hasField; $page = $inputfield->hasPage; // Some test here using $inputfield/$field/$page $inputfield->label_unavailable = 'This is my custom label.'; }); The styling is based on the core InputfieldImage, and rightly or wrongly the equivalent icon there is centered within the button, excluding the thumbnail border. So I don't want to change from that generally. But now that the icon has been changed to a cross instead of the earlier trash icon it does look like it could come up a couple of pixels so I've done that. Of course you can always tweak the styling to your liking with custom CSS as you're doing. Done.
  15. I think you want something like this: // Get all the tags that are used in this client's videos $tags_in_use = new PageArray(); foreach($client->videos as $video) { $tags_in_use->add($video->tags); } // Sort the tags if you like $tags_in_use->sort('title'); // Output the used tags in the sidebar foreach($tags_in_use->sort('title') as $tag) { // ... }
  16. When you enable device mode in the dev tools the user agent will change and therefore the fingerprint will change. I solve this when developing locally with the following in config.php: if(in_array($_SERVER['REMOTE_ADDR'], ['127.0.0.1', '::1'])) { $config->sessionFingerprint = false; } If you're working on a remote site and don't want to change the fingerprint settings then you can use an incognito window when viewing the front-end in device mode.
  17. Not sure why that is. Seems strange considering that system fields can be added by users in the Columns tab. You can use a hook to set the columns and default sort: $wire->addHookBefore('ProcessPageLister::execute', function(HookEvent $event) { /* @var ProcessPageLister $lister */ $lister = $event->object; // Only for Users lister if($lister->parent->id !== 29) return; // Include "created" in default columns $lister->columns = [ 'name', 'email', 'roles', 'created', ]; // Set default sort $lister->defaultSort = '-created'; // Optional: allow user to change sort but reset to default sort each time Access > Users is visited if(!$event->wire()->config->ajax) $lister->sessionSet('sort', ''); });
  18. FieldsetPage fits that description and is part of the core: https://processwire.com/blog/posts/processwire-3.0.74-adds-new-fieldsetpage-field-type/
  19. An old topic but I just hit this problem too, where I want to give an example of Markdown format in the field description without that actually being converted into HTML. I solved it by setting the Inputfield textFormat property in a hook: // Avoid Markdown in description/notes being converted into HTML // Adjust as needed for your Inputfield type and field name $wire->addHookAfter('InputfieldTextarea::renderReadyHook', function(HookEvent $event) { /** @var InputfieldTextarea $inputfield */ $inputfield = $event->object; if($inputfield->name === 'my_field_name') { $inputfield->textFormat = Inputfield::textFormatNone; } });
  20. You can learn from studying the Helloworld module: https://processwire.com/modules/helloworld/ From the readme:
  21. I don't think there is any module that does exactly what you're asking about, but I expect it wouldn't be that hard to achieve without needing any module. We probably need to hear a longer explanation of what you're wanting to do. If the pages of the "book" can be grouped together in the tree in the form... Book title - Chapter ...or... Book title - Chapter -- Subsection --- etc ...then you can create your navigation links using $page->children(), $page->next(), $page->prev() etc. Or if the pages are scattered throughout the site but need to be grouped together for use in a book then you can use a Page Reference field to select all the pages that make up the book. As the book is browsed you can keep track of the fact the visitor is viewing the pages as a book by passing a URL parameter on each navigation link like ?book=my-book-title and this will let you work out the previous and next pages for use in the navigation. If you want to divide the long text into multiple pages on save then you can use a Pages::saveReady hook to parse the HTML and find the tags that you want to split on, then create new pages with the split content using the API. Or if you want to keep the long text in one piece but paginate it on the front-end then you could take a look at TextformatterPagination.
  22. I don't think FieldtypeComments will be able to support those because they require their own dedicated fieldtypes to hold the data. So you would need to create a custom form to handle those, and if the images / page reference needs to be connected with individual comments then you probably need a totally custom comments implementation where you use a page-per-comment behind the scenes. But coming back to the original issue: one way you could work around this is to list all the comments on the parent page, but if a person wants to add a comment they click a link to submit the comment on the child page. If that child page should only be used to submit a comment and not to display any other information then you could use a URL parameter (or alternatively a URL segment) in the link and if the page is loaded without that parameter it redirects back to the parent page. So in the parent page template: <?php foreach($page->children as $child): ?> <h3><?= $child->title ?></h3> <?= $child->comments->render() ?> <a href="<?= $child->url ?>?submit_a_comment=1">Submit a comment</a> <?php endforeach; ?> And in the child page template: <h3>Submit a comment</h3> <?php // Show the comment form echo $page->comments->renderForm(); // If the submit_a_comment URL parameter is not present then redirect to parent page // This must go after the form render so that comment submissions will be processed before redirecting if(!$input->get('submit_a_comment')) $session->redirect($page->parent->url); ?>
  23. @marie.mdna, I tested and can confirm the problem when there are multiple comment forms relating to different pages all rendered on the same page. I'm not sure if FieldtypeComments is intended to support that sort of use but I don't see why it shouldn't. I suggest opening a GitHub issue for this so Ryan can take a look. https://github.com/processwire/processwire-issues/issues
  24. Welcome to the PW forums @marie.mdna! I suspect that the problem is caused by the wrong page ID being set in the hidden page_id field of the comment form. You could try manually setting the hidden fields by replacing... ...with... <input type='hidden' name='page_id' value='{$post->id}' /> <input type='hidden' class='CommentFormParent' name='parent_id' value='0' />
  25. Then you'll want to get the PageArray of selectable pages as shown in the earlier hook: $selectable_pages = $page->getInputfield('your_page_reference_field')->getSelectablePages($page); Then you can use ->eq() to get any item in the PageArray by its index/position, and use a switch statement to do different things accordingly. // Get all the selectable pages that apply when "your_page_reference_field" is used on $page $selectable_pages = $page->getInputfield('your_page_reference_field')->getSelectablePages($page); // Compare the value of $page->your_page_reference_field against the pages in various positions of $selectable_pages switch($page->your_page_reference_field) { case $selectable_pages->eq(0): // The first selectable page is selected require ('assets/bookingstatus/bookingstatus_step1.inc.php'); break; case $selectable_pages->eq(1): // The second selectable page is selected require ('assets/bookingstatus/bookingstatus_step2.inc.php'); break; case $selectable_pages->eq(2): // The third selectable page is selected require ('assets/bookingstatus/bookingstatus_step3.inc.php'); break; default: // Some other page is selected so handle that scenario... }
×
×
  • Create New...