Jump to content

Robin S

Members
  • Posts

    5,039
  • Joined

  • Days Won

    340

Everything posted by Robin S

  1. Suppose you have an images field and you want editors to upload a specific number of images to that field. Using a hook in /site/ready.php you can display a field error in Page Edit if the number of images in the field does not match the required number. Just like the standard "required" behaviour, the requirement does not prevent the field being saved if the number of images is not correct so you would still want to check the image count in your template. $wire->addHookAfter('InputfieldImage::processInput', function(HookEvent $event) { $inputfield = $event->object; // Only for this field if($inputfield->hasField != 'images') return; // Only in ProcessPageEdit if($this->process != 'ProcessPageEdit') return; $page = $this->process->getPage(); // Only for this template if($page->template == 'home') { if(count($inputfield->value) !== 4) $inputfield->error("Please upload exactly 4 images to this field"); } });
  2. Hi @adrian I just discovered the feature where the Captain Hook panel links the hookable method name to the API Explorer (if it is installed I guess). This is very cool. But just wondering if you could have it open the API Explorer in a new tab, to avoid navigating away in the current tab?
  3. It's often better to use a PW page for your AJAX url than a standalone PHP file - just create a special template / template file / page for the purpose and call it in your AJAX function. That way everything in PW, init.php, etc, is available just like normal.
  4. Yes, see the "Setting restrictions via a hook" section of the first post / readme.
  5. Hmmm, neither of those is a very good transliteration. $sanitizer->pageNameTranslate() gives the better result of prospere-jouplaboum, which is also the same result you get if you paste the name when adding a user via the PW admin. Seems like the core should be using that in PagesEditor instead of the Sanitizer::toAscii option.
  6. This fieldtype module is part of the core but it is not installed by default. Install it via Modules > Install > FieldtypeFieldsetPage
  7. Hi @bernhard, This module's inputfield is not initialising when AJAX-loaded. So when inputfield visibility is set to "Open when populated + Closed when blank + Load only when opened (AJAX)", and inside AJAX-loaded repeater items.
  8. You're right; I created a new issue for this: https://github.com/processwire/processwire-issues/issues/395 I know, I was just kidding a bit because I think for most people fieldgroups are one of the more arcane aspects of PW.
  9. For high mail volumes something like Mailgun is probably better. I've only used WireMail Mailgun in one project so far but it worked great.
  10. I discovered that when you rename a Repeater or RepeaterMatrix field, the template and fieldgroup used for the Repeater items keep the old name. So I wrote a little function for renaming a Repeater field including the associated template and fieldgroup. To be clear, you do not need to use this function to rename a Repeater field in normal circumstances. The Repeater template is a system template so it's not something you see normally, and as for the fieldgroup... what on earth is a fieldgroup, right? So this is just for perfectionists. Or if you are doing something like checking the template name in some hook and you don't want to have to deal with the old field name. /** * Rename a Repeater / RepeaterMatrix field, including template and fieldgroup * @param string $old_name The existing name of the Repeater field * @param string $new_name The new name for the Repeater field */ function renameRepeaterField($old_name = '', $new_name = '') { // Both arguments are required if(!$old_name || !$new_name) { wire('log')->error('renameRepeaterField(): Both $old_name and $new_name arguments are required.'); return; } // Rename repeater field $f = wire('fields')->get($old_name); if(!$f) { wire('log')->error("renameRepeaterField(): Field '$old_name' not found."); return; }; if(!$f->type instanceof FieldtypeRepeater) { wire('log')->error("renameRepeaterField(): Field '$old_name' is not an instance of FieldtypeRepeater."); return; } $f->name = $new_name; $label = str_replace('_', ' ', ucfirst($new_name)); $f->label = $label; $f->save(); // Rename template $t = wire('templates')->get('repeater_' . $old_name); $t->flags = Template::flagSystemOverride; $t->flags = 0; $t->save(); $t->name = 'repeater_' . $new_name; $t->flags = 8; $t->save(); // Rename fieldgroup $fg = wire('fieldgroups')->get('repeater_' . $old_name); $fg->name = 'repeater_' . $new_name; $fg->save(); } // Use the function in a one-off operation like this renameRepeaterField('sucky_old_name', 'shiny_new_name'); The function derives a label for the field by replacing underscores with spaces and capitalising the first letter of the field name. If you want a different label you can just edit the field in admin afterwards.
  11. I have puzzled over this too, but I think the confusion comes from a non-standard use of the word "absolute" in relation to the URL. So ProcessPageEditLink never inserts an absolute URL in that it never includes the protocol or domain. But I think the absolute option means absolute relative to the site root. So the link URL starts with '/' as opposed to the two relative options which can give a link URL like '../some-page/'. The current behaviour is a good thing, because otherwise all links would break when the root domain changes (e.g. going from dev to live environment). But it would help if the meaning of the absolute option was clarified.
  12. Yeah, I think this was in an earlier version of the regions spec and I just got used to using it (so always identifying the region you are modifying with the id attribute, and then adding pw-append / pw-prepend separately when needed). But I see now that it isn't mentioned in the most recent description of the spec. So maybe a bug/oversight that this functionality isn't working with pw-append="some-id". The main bug to watch out for though is this one: https://github.com/processwire/processwire-issues/issues/302 I really hope that it gets fixed sometime soon.
  13. Adding classes with pw-append / pw-prepend is working for me... <body id='html-body' class='bgimage' pw-append></body>
  14. You're probably right. It won't hurt to add the feature and users can make up their own mind what they find easiest to use. The $page argument for that method actually is the page being edited.
  15. @tpr, I guess the question is "Why use ini format in the AOS config when you can just as easily use a hook?" The hook equivalent of the first two items in your screenshot is: $wire->addHookBefore('Field::getInputfield', function(HookEvent $event) { $field = $event->object; $page = $event->arguments(0); // Add word counter for the "title" field for non-superusers if($field->name == 'title' && !$this->user->isSuperuser()) { $field->showCount = 2; } // Set year range for a date field, if template is "news" if($field->name == 'date_created' && $page->template == 'news') { $field->yearRange = '-3:+3'; } }); Comparing the hook option to the AOS config option my thoughts are: Once the hook function is in place and the $field and $page variables defined, the code for each field override is not significantly longer. It's plain PHP, so we're already familiar with the format. It's easier to read the conditionals. It's file-based. It's easy to dump/log within the hook. It saves any additional complexity being needed in AOS.
  16. Okay, big flip-flop ahead... ...thinking some more, maybe this isn't such a good thing to add into AOS. It introduces another "language" to learn for doing something that is already possible with hooks. And @abdus has recently posted a tutorial for how to add other field settings into the template overrides that allows the admin GUI to be used. And I can see these ini-style settings being difficult to debug. Don't know, I'm really in two minds about it. Be good to hear what others think.
  17. Awesome! I can see this being really powerful, and a nice alternative to working with hooks. What do you think about adding an option for using a file to define these settings? For anything but the briefest snippets I much prefer working in my IDE (version control, etc). It could be a checkbox to activate the file-based option, or just check if "field-overrides.ini" exists in /site/modules/AdminOnSteroids/.
  18. @Violet, I just made a fix to the code snippet... // Return if body field absent or unchanged if(!$page->body || !$page->isChanged('body')) return;
  19. I might be wrong, but my understanding is that the ACF/Purifier settings for a CKEditor field only affect content that goes through the CKEditor inputfield and is then saved to the database. A textformatter on the other hand never saves its changes to the database and it isn't involved with the inputfield - it just makes changes on-the-fly as the content is output to the front-end. Another thought: if you have multiple textformatters applied, check to see if the order they are applied makes a difference.
  20. Child pages can be good when: You think it will be helpful for the relationship to be shown in the URL to the pages: /manufacturers/dodge/challenger/ Although it is also possible to 'fake' a page URL using URL segments. The child will exclusively belong to that parent (it doesn't belong to multiple categories). If either of these is not the case then you are better off with Page Reference fields. So in your example, you have fish in an aquarium. If by "fish" you mean "species of fish" then you wouldn't want to have these as child pages of an aquarium, because multiple aquariums might have the same species of fish and you don't want to duplicate the species pages.
  21. There shouldn't be any iframe tags involved - you simply insert the URL to the video (not an embed snippet or anything like that) in a new paragraph in your CKEditor field.
  22. This module is a textformatter, so it doesn't write anything to the CKEditor field. As long as you can insert a link URL into your field as text without interference from HTML Purifier then there shouldn't be any problem.
  23. @Macrura if $widget is a page, then try this... $widget->getFormatted('dw_color')
  24. Another option which avoids the need to parse and modify the links on every frontend page load (as a textformatter does), you could just do it once when a page is saved. The example below (add to /site/ready.php) uses Simple HTML DOM as the parser: // Change 'body' to whatever your CKEditor field is named $wire->addHookAfter('Pages::saveReady', function(HookEvent $event) { $page = $event->arguments(0); // Return if body field absent or unchanged if(!$page->body || !$page->isChanged('body')) return; // Load Simple HTML DOM from site root require_once $this->config->paths->root . 'simple_html_dom.php'; // Create DOM from body field $html = str_get_html($page->body); // Get all the links $links = $html->find('a'); foreach($links as $link) { $href = $link->href; // For any link that is not relative and does not start with the site httpRoot... if(strpos($href, '/') !== 0 && strpos($href, $this->urls->httpRoot) !== 0) { // Set rel and target attributes $link->rel = 'nofollow'; $link->target = '_blank'; } } // Set the results to the body field $page->body = $html->save(); });
  25. Hi @adrian, Might be a silly question, but just wondering why the dump output doesn't appear in the same order that the dumps occur in. So if I do... ...how come the output order is reversed?
×
×
  • Create New...