Jump to content

Robin S

Members
  • Posts

    4,791
  • Joined

  • Days Won

    303

Everything posted by Robin S

  1. @MarkE, besides the autojoin setting in admin that's mentioned in Ryan's post, you can also set autojoin programmatically when you get one or multiple pages. For multiple pages ("find") see the blog post: https://processwire.com/blog/posts/find-faster-and-more-efficiently/ And if you only want a single page ("get") then you can use "joinFields" in the $options argument, e.g. Edit: it seems you can use the "field=" syntax described in the blog post with $pages->get() and $pages->findOne() too...
  2. Field values for a page are loaded from the database on demand (i.e. as you request them) unless you have set them to be "autojoined":
  3. I agree that it's not a major issue, but it would still be nice to slim down the total TracyDebugger size because it's a module that receives frequent updates (thanks! ❤️) and so I'm downloading it regularly. Ace makes up approximately 80% of the total TracyDebugger size. Could it maybe be loaded via a CDN? https://cdnjs.com/libraries/ace Also, I've heard good things about Monaco (possible replacement for Ace): https://cdnjs.com/libraries/monaco-editor
  4. @gebeer, the findReady method is working for me: $wire->addHookAfter('ProcessPageSearch::findReady', function(HookEvent $event) { $selector = $event->return; if($event->wire()->user->isSuperuser()) return; // If the selector looks like it comes from a particular autocomplete Page Reference field // (I wish this method provided a better way of working out where the selector is coming from) if(strpos($selector, 'parent_id=1329, templates_id=62,') === 0) { $selector .= ", include=all"; $event->return = $selector; } });
  5. @eelkenet, cool that you were able to find a solution! Here's another way you could add disabled section items into the Page Reference AsmSelect using the PW API. It avoids getting each page individually in a loop so probably a bit more efficient. // Add dummy items to the selectable pages to act as section headings $wire->addHookAfter('InputfieldPage::getSelectablePages', function(HookEvent $event) { /** @var InputfieldPage $inputfield */ $inputfield = $event->object; $field = $inputfield->hasField; $selectable = $event->return; $t = null; $i = 1; if($field && $field->name === 'my_page_reference') { foreach($selectable as $p) { if($p->template->name !== $t) { $section = new NullPage(); $section->id = "section{$i}"; $section->title = mb_strtoupper($p->template->label) . ' ––––––––––––––––––––'; $selectable->insertBefore($section, $p); $t = $p->template->name; $i++; } } $event->return = $selectable; } }); // Set the dummy options to disabled $wire->addHookAfter('InputfieldAsmSelect::renderReadyHook', function(HookEvent $event) { /** @var InputfieldAsmSelect $inputfield */ $inputfield = $event->object; $field = $inputfield->hasField; if($field && $field->name === 'my_page_reference') { foreach($inputfield->options as $value => $label) { if(substr($value, 0, 7) === 'section') { $inputfield->addOptionAttributes($value, ['disabled' => 'disabled']); } } } });
  6. You could apply the purify sanitizer when the field value is saved by hooking InputfieldTextarea::processInput(). But looking at it another way, it isn't really possible to guard against a malicious superuser - they could destroy the site in any number of ways. Therefore you have to accept that superuser is a role for trusted users only.
  7. Hi @tomasanjosbarao, I don't think I understand your post. If you can provide steps to reproduce some problem with the module I'm happy to investigate.
  8. @eelkenet, unfortunately I think you have a difficult road ahead if the optgroups are really important to your use case. Probably you would need to create your own custom inputfield using something like Selectize or Select2. It's a shame, but AsmSelect doesn't support optgroups. It's not adding the optgroups to the underlying select markup that's the big problem, it's that AsmSelect doesn't account for optgroups when it builds the "fake" select from the underlying hidden select element. There was a pull request to add optgroup support the standalone jquery-asmSelect back in 2015 but it was never merged into either the standalone version or the InputfieldAsmSelect included in the PW core. You might think that Selectize would be a simple solution because it supports optgroups out of the box and PW already provides an API for Selectize inputfields via InputfieldTextTags. But unfortunately no optgroup support was included in InputfieldTextTags because the addTag() and addOption() methods only support individual options without the ability to add options in a group as per InputfieldSelect::addOption(). And as far as I know you can't do something like supply the entire select markup to InputfieldTextTags. P.S. the title of the topic is bit confusing because InputfieldSelectMultiple is a different thing to InputfieldAsmSelect. InputfieldSelectMultiple does support optgroups - you can add them via InputfieldSelectMultiple::addOption().
  9. Does the template in question explicitly allow the role to edit, or is the access inherited from parent pages? If you haven't explicitly set the template access I think the likely solution is to set that access. You have to remember that Lister is not creating its list by individually checking the access of every page and every page's parents. Rather it's creating a selector string that produces the list. I can see some code in Lister that looks like it does take inheritance from the immediate parent into account if there is a "parent=" item in the Lister filters. But I think it would be more practical for you to explicitly set the edit access on templates that you want a role to be able to edit. Personally I always set the access for every template in my site because I want to be sure I've made a conscious decision to control that access rather than let it potentially drift down unnoticed from some parent. I've never understood what reason there could be to not explicitly set the access controls on a template (maybe someone can explain the scenario where that is useful?) Getting off topic now, but I have a module that makes it quick to check and set the access controls on templates across the site - I'll write up the readme and release it soon.
  10. By default Lister should automatically show unpublished pages that the user is allowed to edit as long as the Lister filters are limiting by template. So if your user is allowed to edit template "basic-page", and the Lister filters include "template=basic-page" then the user will be able to see unpublished pages (without needing to have a specific "include" item in the Lister filters). But if you don't have a "template=" item in the filters, or you are filtering by multiple templates and the user doesn't have edit permission for all the included templates, then the user will not be allowed to see unpublished pages. See here for the relevant code.
  11. This isn't the first star rating module for ProcessWire, but I wanted some particular config options and to have the inputfield be usable within FormBuilder. FieldtypeStars The inputfield of FieldtypeStars uses a star rating interface to set a float value. The fieldtype extends FieldtypeFloat. The inputfield has no external dependencies such as jQuery or Font Awesome and can be used in FormBuilder. Config Using InputfieldStars in FormBuilder In order to add a Stars field to a FormBuilder form you must first enable "Stars" in the "Allowed Input Types" field in the FormBuilder module config. https://github.com/Toutouwai/FieldtypeStars https://processwire.com/modules/fieldtype-stars/
  12. Yes, but be aware that this resolves the error by simply stripping out the asterisk. Which might be okay if the asterisk isn't an important part of the search phrase, but if you want to match pages according to the presence of the asterisk then you'll need to whitelist it.
  13. The sanitizer method intended for text that will be used as a selector value is $sanitizer->selectorValue(). See for example in Ryan's demo skyscrapers site. By default this sanitizer will filter out the asterisk, presumably because it's a character used within some selector operators. But it looks like if you whitelist it in the $options argument and it will be retained and the error is avoided because the value gets wrapped in quotes. $q = $sanitizer->selectorValue($input->get('q'), ['whitelist' => ['*']]);
  14. The settings are made on the module config page and that means they are only accessible to superusers. When putting pages at the bottom this is usually for "admin helper" purposes that a superuser would set up, but I would think that forcing pages to the top is more a content management function that needs to be manageable by non-superusers. It might be something that is better handled with a hook or just a Page Reference field. Can you describe the use case where you want pages kept at the top? Then I can consider it or suggest alternative ways of achieving it.
  15. Well if you are talking about writing your own SQL query that's fine and you're totally free to do that in PW. But your question related to the use of PageFinder selector strings, and I'm just trying to help you by explaining what values are valid for the "sort" keyword.
  16. When you sort by "something" this means that "something" is the property you are sorting on, and the sorting will occur either ascending or descending by the value of the property. In cases where your sorting involves a database query such as $page->find() then the property you are sorting on needs to be a column in the database that the ORDER BY can apply to. An example: if you have a field "fruit" then you can sort on it because it has an ascending or descending value in its database column: "apple, banana, cherry" or "wineberry, tangelo, strawberry". But you can't sort by "fruit=banana" because that isn't something that has a range of ascending or descending values and doesn't correspond to any single column in the database. I understand what you're trying to do but this isn't something that can be accomplished by a single sort property - you have to do more of the work yourself and use more than one selector, merging the results together. The Find Merge module might allow you to do this in a simple way: // Define selectors to merge results of // You could also define any secondary sorting for each selector as needed, e.g. sort=title $selectors = [ 'template=repeater_requests, help_roles=1', // These results will come first 'template=repeater_requests, help_roles!=1', // These will be added after to make up the limit if needed ]; // Get results // You can use "start" in the options argument if needed (see module readme) $results = $pages->findMerge($selectors, 20);
  17. Maybe this? https://processwire.com/blog/posts/processwire-core-updates-2.5.14/#multiple-templates-or-parents-for-users Just my two cents: based on forum topics and GitHub issues my impression is that people encounter troubles pursuing this strategy. I've always thought that leaving the user pages where they are by default and using URL segments for profile pages or similar is a much safer bet.
  18. Thanks Adrian, that's a really good idea! I think a single save button for the whole panel would be good because it might be useful having all the dumps that occurred together be connected in that way. Although having individual save buttons would be fine too - I think I'll find it very useful in either case. Edit: could the archived dumps be given a label when saving them? Like maybe a text input that gets populated with the current datetime by default but can be added to or overwritten before clicking the archive button?
  19. It took some investigating and it would be great to have this made more obvious in any documentation for $config->pagefileSecure... Behind the scenes pagefileSecure is using $files->send(): And $config->fileContentTypes forces download for certain extensions based on whether the content type is preceded by a + sign. You can override the default for the pdf extension in your /site/config.php and then the files should display in the browser: $config->fileContentTypes('pdf', 'application/pdf'); // No plus sign before the content type
  20. In v0.2.0 I've added a Pageimage::megapixelsDimensions() method that returns just the dimensions needed to resize an image to a target megapixel value. I used this recently to create a gallery of sponsor logos in normal and high dpi variations. Example from the updated readme: foreach($page->logos as $logo) { $dimensions = $logo->megapixelsDimensions(0.01); $width = $dimensions['width']; $height = $dimensions['height']; $width2x = $width * 2; $height2x = $height * 2; echo "<img src='{$logo->size($width, $height)->url}' srcset='{$logo->size($width, $height)->url} 1x, {$logo->size($width2x, $height2x)->url} 2x' alt='Logo' width='$width' height='$height'>"; } I've also added the module to the PW directory.
  21. A feature idea maybe for a rainy day... Sometimes I find I want to save a record of what is in the Dumps panel. I usually just copy/paste to a text document but it would be cool if there was a download button that saved the contents of the Dumps panel to an HTML file. That would be nicer because of the better formatting and expand/collapse features. Perhaps not so simple to do because I guess it would be best to embed any needed CSS and JS and the HTML file creation and download would need to happen via JS. So maybe not worth the trouble if it's a pretty niche need, but just thought I'd jot the idea down while it was fresh.
  22. You could just use ->parent twice: $parent = $page->parent; $grandparent = $parent->parent;
  23. @DrQuincy, you could use JavaScript to remove any disallowed characters from the input if the href is a tel link: $wire->addHookAfter('ProcessPageEditLink::execute', function(HookEvent $event) { $event->return .= <<<EOT <script> $(document).ready(function() { $(document).on('blur', '#link_page_url_input', function() { var href = $(this).val(); // If the href is a tel link if(href.startsWith('tel:')) { // Remove any disallowed characters href = href.replaceAll(' ', '').replaceAll('(', '').replaceAll(')', ''); $(this).val(href).trigger('change'); } }); }); </script> EOT; });
  24. Welcome @protro 🙂 What you have is fine. This is another way you could do it, which is perhaps a bit more readable: $items = new PageArray(); foreach($page->children as $child) { if($child->hasChildren) { $items->add($child->children); } else { $items->add($child); } } $items->sort('-date'); And if the objective happens to be "I want all the descendants that don't themselves have descendants" then this is potentially quite a bit more efficient because it's only a single DB query: $items = $page->find("children.count=0, sort=-date");
  25. @Guy Incognito, could you please reopen the GitHub issue because I think there is a bug that needs attention? I've added a comment to the issue.
×
×
  • Create New...