Jump to content

Robin S

Members
  • Posts

    5,064
  • Joined

  • Days Won

    341

Everything posted by Robin S

  1. This might be a somewhat niche module but I had a need for it and maybe others will also find it a useful development helper. Lister To Clipboard Easily copy a selector for the current Lister filters or selected results to the clipboard. For superusers only. Why? Lister or Lister Pro is handy for finding pages according to certain page attributes or field values and you can see the matched pages in a results list. Sometimes I want to run code on some or all the Lister results. Lister Pro allows results to be processed through Page Action modules but there are a couple of downsides to this: To execute custom code you would have to create a custom Page Action module and this may not be worth the trouble for a one-off operation. If you want to process only selected individual pages you can only select items from one page of the results. If you navigate to a different page within the paginated results the selection is lost. Lister To Clipboard gives you an easy way to copy a selector for the current Lister filters or a selection within the results so you can paste it into the Tracy Debugger Console or use it elsewhere in your code. Usage In Lister (Find) or in a Lister Pro instance, create filters to match the pages you want to target. If you want to select individual pages within the results, click an empty area of the cell within the first column (i.e. don't click directly on the page title). The cell will get a green background to indicate that it is selected. If there is more than one page of results you can move around the pagination to select more pages. Below the Lister results there is a blue box showing a selector string that will find the pages shown in your Lister results (or your selection within those results) when used in $pages->find(). Click the copy icon to copy the selector to the clipboard, then you can paste it into the Tracy Debugger Console or wherever you want to use it. https://github.com/Toutouwai/ListerToClipboard https://processwire.com/modules/lister-to-clipboard/
  2. It's working without problems for me.
  3. @nicolant, ProcessWire doesn't allow filenames to include dots, perhaps because Images fields use a dot to separate the variation suffix from the basename and Images and Files fields share some of the same code. If using dots in the filename is essential for some reason and you are willing to use an experimental module you could try this: https://github.com/Toutouwai/FieldtypeFileUnrenamed
  4. If by "featured" you mean "linked to within a CKEditor field" then it's pretty easy. You just upload the file to the first page it will be used on (Page A), and on any of the other pages you use the CKE link dialog to select Page A and then select the file.
  5. Check out the blog post that introduced InputfieldTextTags: https://processwire.com/blog/posts/pw-3.0.177/#using-with-options-fields If you use a Page Reference field for your tags then you can add new tags via the inputfield if the field settings are configured to allow it. From the blog post:
  6. One more possibility: get your non-user pages by path instead of by ID. If you use PagesLoader::getByPath() it should be just as robust as getting by ID because page path history will handle any renaming or moving of pages. And as a bonus the code is more readable because it's more obvious what page is retrieved by '/about-us/sustainability/' than by 24875. $p = $pages->loader()->getByPath('/about-us/sustainability/', ['useHistory' => true]));
  7. I haven't been a regular user of the RuntimeMarkup module so I'm not qualified to talk about it. Maybe the best thing would be for you to try both modules and see which one suits you better.
  8. I'm not sure what the reason for the ID limitation is, but you could set the value of each option to the integer you want:
  9. Thanks for the report. It's hard to know when FormBuilder methods were added because there are no @since tags in the code. In v0.1.5 I've changed to older FB methods for better backwards compatibility.
  10. @AAD Web Team, if you're wondering why status!=hidden doesn't work in this selector it's because status keywords like that are only supported in PageFinder selectors like $pages->find() that query the database, and not by selectors that match against a PageArray in memory. And although the docs don't make this clear $page->parents() actually adds all the parents one by one into a PageArray and then filters that PageArray by the selector. See here. It is a bit confusing that $page->children($selector) goes through PageFinder but $page->parents($selector) doesn't.
  11. We're on the same wavelength - I meant turning it off in the Panel Selector. ? Ending the session if/when someone does that sounds like a good idea.
  12. The no time limit sounds good, but I usually close the panel after I've switched user because it takes up screen real estate. Maybe just the End Session button would be enough, or maybe force the User Switcher icon into the debug bar when it's active (currently you can exclude that icon from the debug bar while a User Switcher session is active, although I don't know why anyone would do that). Thanks.
  13. Hi @adrian, Sometimes I want to spend a whole day using User Switcher so I'm wondering if the maximum session length could be increased beyond 60 minutes. I'm sure there must be a good reason why it has a limit, so if it would potentially cause problems to raise the limit for everyone maybe there could be some $config option that would define the session limit? Thanks.
  14. Yep, perfect, thanks! Just to spell it out for any future readers... if($session->tracyUserSwitcherId) { // Run this code only if browsing via User Switcher //... }
  15. $user->isSuperuser() will return false just like you show in your screenshot, which is expected because User Switcher is active. But what I'm wanting is something like the pseudocode $user->isReallySuperuser() that would return true when User Switcher is active. Now it doesn't need to be some method of $user, but I'm wondering if Tracy might be able to offer something that allows for a simple way to check if User Switcher is active and being used by a superuser (not sure if users less than superuser could even access User Switcher - I've never needed to allow that). Or maybe Tracy already does expose something that could be easily checked for this purpose?
  16. Hi @adrian, If I'm working on a site that other users have access to I'll often do something like: if($user->isSuperuser()) { // Run this code for me only //... } But if I'm presenting as another user via the User Switcher panel then this won't work. Do you know of an easy way to check if the current user is in reality a superuser but is currently browsing via User Switcher? Thanks for any suggestions.
  17. If you can create a simplified demonstration case you could open a core GitHub issue because id.sort is supposed to cause results to be in the order of the supplied IDs. For now you could follow the approach used in my FindMerge module, where array_slice() is used to get a slice of the IDs according to the current page number: https://github.com/Toutouwai/FindMerge/blob/cbc6f43138508a52ae095c7041dbb969cc7d7bf7/FindMerge.module#L86-L99
  18. @Arcturus, I just released v0.1.4 which adds a hookable method for users like yourself who want to do advanced customisation of the CKEditor inputfield, so you don't need to hack the module itself. See the updated readme. Setting the stylesSet property is working for me. $wire->addHookAfter('InputfieldMarkupCKEditor::ckeReady', function(HookEvent $event) { /** @var InputfieldCKEditor $cke */ $cke = $event->arguments(0); /** @var FormBuilderForm */ $form = $event->arguments(1); /** @var FormBuilderField $field */ $field = $event->arguments(2); if($form->name === 'test_form' && $field->name === 'my_cke_markup_field') { $cke->contentsCss = '/site/templates/MarkupCKEditor/contents.css'; $cke->stylesSet = 'ckstyles:/site/templates/MarkupCKEditor/ckstyles.js'; } }); CKEDITOR.stylesSet.add( 'ckstyles', [ { name: 'Special heading', element: 'h2', attributes: { 'class': 'special-heading' } } ]); Make sure the prefix you are using in the setStyles property matches the style set name in the JS file.
  19. v0.2.0 of the module is released, which is a fairly major update that brings support for Repeater, FieldsetPage and Repeater Matrix fields. Using the "Field widths" field you can quickly set the width of inputfields within a Repeater/FieldsetPage field or within each Repeater Matrix type. Repeater: Repeater Matrix:
  20. In your CKEditor fields setting > Input tab > Custom Config Options: scayt_autoStartup: true
  21. @formulate, it sounds like you want to have some prioritised subset of the results interleaved with the rest of the results, so they are distributed rather than grouped near the end where they would otherwise appear. There isn't any "sort" value you can use in a selector to do this because sort can only work by ordering results based on some specific column in the database, and no such column exists for your case. So like @DaveP said, you need to get all the results and then apply the sort order yourself. But when you have large numbers of results you want to avoid loading all the results in a PageArray. It's more efficient to work with just the IDs and then get paginated results from those IDs, and to do that you can use the id.sort feature that @Jonathan Lahijani mentioned. Here's a demo of how you might do this. This is simplified to just use templates to distinguish between the priority results and the other results but you will be able to adapt it to your case. // Do the custom sorting using only page IDs for efficiency $priority_ids = $pages->findIDs("template=colour"); $other_ids = $pages->findIDs("template=country"); $merged_ids = []; // Loop over the $other_ids (this should be the larger of the two arrays) foreach($other_ids as $key => $id) { // Use modulo operator to insert one priority ID for every two other IDs if($key % 2 === 0) { $merged_ids[] = array_shift($priority_ids); } $merged_ids[] = $id; } // If there happen to be any priority IDs left over when the loop is finished, add them at the end if(count($priority_ids)) $merged_ids = array_merge($merged_ids, $priority_ids); // Now use id.sort to get pages matching the IDs in paginations of 20 $results = $pages->find([ 'id.sort' => $merged_ids, 'limit' => 20 ]);
  22. 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.
  23. 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.
  24. 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/
  25. The setting is now called "Page containing default/fallback value for this field"
×
×
  • Create New...