Jump to content

Robin S

Members
  • Posts

    5,007
  • Joined

  • Days Won

    333

Everything posted by Robin S

  1. Using Tracy Debugger to dump the name of the submit button can give you a clue... $wire->addHookAfter('InputfieldSubmit::processInput', function(HookEvent $event) { $inputfield = $event->object; bd($inputfield->name, "inputfield->name"); }); So there are two submit buttons in Page Edit that get processed: the Save button and the Trash button on the Delete tab. Rather than hooking InputfieldSubmit::processInput you can use the dedicated hookable method that performs the save actions: $wire->addHookAfter('ProcessPageEdit::processSubmitAction', function(HookEvent $event) { $value = $event->arguments(0); if($value === 'send_registration') { // Do your action here... } });
  2. Thanks, I'm glad you like it. ? The "Admin theme settings (Uikit)" options don't exist for the standard Fieldset fieldtype (FieldsetOpen) so that wouldn't work, and in any case the location of the module settings fields doesn't determine whether or not they can appear in template context. But in the newly released v0.1.6 I have added support for defining the Minimal Fieldset settings in template context so this should cover what you're wanting to do.
  3. Welcome to the PW forums @Rossie! This part... ...finds all the pages that contain at least one image in the gallery20 field that has furniture_list_type=3390 in the image's custom fields. But those pages can also contain images that don't have furniture_list_type=3390 in their custom fields. So if you only want to output certain images from the gallery20 field you need to use a WireArray find() selector to get those images. Your code would look something like this: // Find the pages that have at least one image in the gallery20 field with furniture_list_type=3390 $imagePages = $pages->find("template=makers-child, gallery20.furniture_list_type=3390") ; // For each of those pages... foreach($imagePages as $p) { // Find the images in the gallery20 field with furniture_list_type=3390 $chair_images = $p->gallery20->find("furniture_list_type=3390"); echo "<ul>"; // Loop over the chair images foreach($chair_images as $image) { echo "<li><img src='{$image->url}'>{$image->furniture_list_type}</li>"; } echo "</ul>"; }
  4. Here is a demo module: <?php namespace ProcessWire; class ProcessSaveSettings extends Process implements ConfigurableModule { /** * Module information */ public static function getModuleinfo() { return array( 'title' => 'Site Settings', 'summary' => 'A demo module showing how inputfield values can be saved in the module config.', 'version' => '0.1.0', 'author' => 'Robin Sallis', 'icon' => 'cogs', 'requires' => 'ProcessWire>=3.0.0, PHP>=5.4.0', 'page' => array( 'name' => 'site-settings', 'title' => 'Site settings', 'parent' => 'setup', ), ); } /** * Execute */ public function ___execute() { $modules = $this->wire()->modules; $input = $this->wire()->input; /** @var InputfieldForm $form */ $form = $modules->get('InputfieldForm'); // Add an inputfield /** @var InputfieldText $f */ $f = $modules->get('InputfieldText'); $f_name = 'site_name'; $f->name = $f_name; $f->label = 'Site name'; $f->value = $this->$f_name; $form->add($f); // Add another inputfield /** @var InputfieldSelect $f */ $f = $modules->get('InputfieldSelect'); $f_name = 'header_colour'; $f->name = $f_name; $f->label = 'Header colour'; $f->addOption('#F00', 'Red'); $f->addOption('#0F0', 'Green'); $f->addOption('#00F', 'Blue'); $f->value = $this->$f_name; $form->add($f); // Add more inputfields to the form here... /** @var InputfieldSubmit $s */ $s = $modules->get('InputfieldSubmit'); $s->name = 'save_settings'; $s->value = 'Save settings'; $form->add($s); // If the form was submitted... if($input->save_settings) { // Let the inputfield modules process their input $form->processInput($input->post); // Get all the inputfields in the form $inputfields = $form->getAll(); $data = []; // Add the inputfield values to $data foreach($inputfields as $inputfield) { // Skip the submit button if($inputfield->type === 'submit') continue; $data[$inputfield->name] = $inputfield->value; } // Save the config data $modules->saveConfig($this, $data); // Redirect: https://en.wikipedia.org/wiki/Post/Redirect/Get $this->wire()->session->redirect('./'); } return $form->render(); } /** * Config inputfields: required for ConfigurableModule * * @param InputfieldWrapper $inputfields */ public function getModuleConfigInputfields($inputfields) {} } And there are a couple of relevant modules that might suit your needs, or that you could study for learning purposes: https://modules.processwire.com/modules/process-general-settings/ https://modules.processwire.com/modules/settings-factory/
  5. Yes, this is easiest to do if you apply the sorting as the page is saved. So you won't see the sorting immediately after the images are uploaded, but will see the sorting after the page is saved and Page Edit reloads. In the examples below you would add the hook code to /site/ready.php The sort settings for child pages prevents the editor from making any other sort order apart from the one specified. So if you want something like that for images, where the newest images are sorted first, it's very simple: $pages->addHookAfter('saveReady', function(HookEvent $event) { $page = $event->arguments(0); $pages = $event->object; if($page->template == 'your_template') { if($page->isChanged('your_images_field')) { // Sort the images from newest to oldest $page->your_images_field->sort('-created'); } } }); But if you want to sort newly uploaded images first once the page is saved, but still let your editors customise the sort order after that, then you can use this hook: $pages->addHookAfter('saveReady', function(HookEvent $event) { $page = $event->arguments(0); $pages = $event->object; if($page->template == 'your_template') { if($page->isChanged('your_images_field')) { // Get the old version of the page, without the current changes $old_page = $pages->getById($page->id, [ 'cache' => false, 'getFromCache' => false, 'getOne' => true, ]); // Get the names of the existing images on the old page $existing_image_names = $old_page->getFormatted('your_images_field')->implode('|', 'basename'); // Get the newly added images $new_images = $page->your_images_field->find("basename!=$existing_image_names"); // Prepend the new images to the start of the Pageimages WireArray foreach($new_images as $new_image) { $page->your_images_field->prepend($new_image); } } } });
  6. You can use the API for this - covered in this post:
  7. I don't think it's possible to use regex in config.allowedContent, but this seems to do the job: CKEDITOR.on('instanceReady', function(event) { var rules = { elements: { a: function(element) { // If a link href starts with 'javascript:'... if(element.attributes.href.substring(0, 11).toLowerCase() === 'javascript:') { // ...then the href is invalid so remove the link delete element.name; } } } }; event.editor.dataProcessor.htmlFilter.addRules(rules); event.editor.dataProcessor.dataFilter.addRules(rules); });
  8. Here's a hook (add to /site/ready.php) that allows you to set a description and your own help notes for each checkbox in the Status field: // Add some extra notes to the options in the Status field of Page Edit $wire->addHookAfter('ProcessPageEdit::buildFormSettings', function(HookEvent $event) { /** @var InputfieldWrapper $form */ $form = $event->return; $status = $form->getChildByName('status'); if(!$status) return; // Add a description to the field if you like $status->description = 'You can apply various statuses to this page to control its visibility and editability.'; $options = $status->options; // Define your notes here $notes = [ 2048 => 'Peter Piper picked a peck of pickled peppers.', // Unpublished 1024 => 'How much wood would a woodchuck chuck, if a woodchuck could chuck wood?', // Hidden 4 => 'She sells sea shells by the seashore.', // Locked ]; foreach($options as $key => $value) { if(!isset($notes[$key])) continue; $options[$key] .= "[br]{$notes[$key]}[br]&nbsp;"; } $status->options = $options; });
  9. There's a module for that: https://modules.processwire.com/modules/template-tags-edit-list/
  10. I take this to mean you want the names of the user's roles, excluding the guest role, as a pipe separated string that you can use within a selector string. One-liner: $user_roles_string = $user->roles->find('name!=guest')->implode('|', 'name'); Other ways: $user_roles = []; foreach($user->roles as $role) { if($role->name === 'guest') continue; $user_roles[] = $role->name; } $user_roles_string = implode('|', $user_roles); $user_roles_string = ''; foreach($user->roles as $role) { if($role->name === 'guest') continue; $user_roles_string .= "$role->name|"; } $user_roles_string = rtrim($user_roles_string, '|');
  11. @Roope, thanks for the update. However, the update wasn't encoding email addresses for me. After some debugging I think the problem is that this... "((?:<(?:head|script|textarea|option|output)).*(?:<\/(?:head|script|textarea|option|output)>))" ...and this... if(!in_array(substr($str, 0, 5), array('<head', '<scri', '<text', '<opti', '<outp', '<inpu', 'value', 'label', 'data-'))) { ...result in the HTML getting split on the <header> tag and then email addresses following that tag are not encoded.
  12. @tpr, could you please make the styles that AOS applies to Select2 more targeted so that it's possible to use Select2 separately in the PW admin without being affected by AOS styles? At the moment there are AOS styles like this... .select2-selection.select2-selection--single, .select2.select2-container, span.select2-dropdown { width: auto !important; min-width: 300px !important; max-width: 640px; } ...which will apply to every Select2 instance and are impossible to override to get back the inline style that Select2 uses to set the dropdown width dynamically. It would be better if these could be something like: .aos-select2.select2-selection.select2-selection--single, .aos-select2.select2.select2-container, span.select2-dropdown { width: auto !important; min-width: 300px !important; max-width: 640px; } See "dropdownCssClass" and "selectionCssClass" in the Select2 options. Thanks!
  13. "exe" is among the file extensions that is blocked in WireUpload.php /** * Disallowed extensions for uploaded filenames * * @var array * */ protected $badExtensions = array('php', 'php3', 'phtml', 'exe', 'cfm', 'shtml', 'asp', 'pl', 'cgi', 'sh'); But it turns out you can override this by setting your own custom array of blocked extensions in your /site/config.php // Remove "exe" from array of file extensions blocked by WireUpload $config->uploadBadExtensions = array('php', 'php3', 'phtml', 'cfm', 'shtml', 'asp', 'pl', 'cgi', 'sh'); Of course exe is probably blocked by default for a reason so you would want to do your own research about possible risks involved in allowing such files on your server.
  14. You could adapt this:
  15. Some hook code is here:
  16. v0.3.2 released. This version reverts to the hook methods used in v0.2.3 and earlier of this module now that the core circular reference issue was fixed in PW v3.0.166. To upgrade to v0.3.2 you must be running PW v3.0.166 or newer, which is currently only available on the dev branch.
  17. Yeah, we all struggle with that sometimes. ? I did a bit of experimenting and here's another way the language options can be removed from the title field: // Single-language title field for "test-template" at Page Add $wire->addHookAfter('ProcessPageAdd::getAllowedTemplates', function(HookEvent $event) { $tpls = $event->return; $t = $event->wire()->templates->get('test-template'); if(isset($tpls[$t->id])) $tpls[$t->id]->noLang = 1; $event->return = $tpls; }); // Single-language title field for "test-template" at Page Edit $wire->addHookAfter('ProcessPageEdit::buildFormContent', function(HookEvent $event) { /** @var InputfieldForm $form */ $form = $event->return; $page = $event->object->getPage(); if($page->template == 'test-template') { $title = $form->getChildByName('title'); if($title) $title->useLanguages = false; } });
  18. I might be misunderstanding something (I don't normally work on multi-language sites), but isn't it optional to enter page titles in any language other than the default? The user isn't forced to add a title in all enabled languages as far as I can see. So it seems like it's a question of user education more than anything else, the lesson being "only create page titles in languages that you need", which is really part of a more basic general lesson that any CMS user must learn: "only fill out fields that you have information for".
  19. Thanks for the prompt response, that fixes it here.
  20. Hi @adrian, In the Mail Interceptor panel, special characters are scrambled in the From field: I think this might be glitch in the Mail Interceptor panel rather than a WireMail issue because the From value seems to render properly in my email client. But if it isn't a Tracy issue and is actually a WireMail problem I'd want to report it to Ryan. Could you take a look when you have a chance? Thanks.
  21. @Macrura has created a couple of modules for adding help documents to the admin: Myself, I just create a PW page (hidden from non-superusers in the admin) that contains instructions for users. I use some custom jQuery in the admin to append an "Instructions" view link to the admin footer so the document is always easily accessible from any page. To provide some intervention against duplicate pages you could try a hook like this: $pages->addHookAfter('added', function(HookEvent $event) { $page = $event->arguments(0); $pages = $event->object; // For pages with a particular template... if($page->template == 'basic_page') { // Check for existing page with the same title // You could get fancy by making this more fuzzy // E.g. exclude short words and then look for titles that contain the remaining words $existing_page = $pages->get("template=basic_page, title={$page->title}"); if($existing_page->id) { // You could use the edit URL or view URL as appropriate $url = $existing_page->editURL; $event->wire()->warning("There is an existing page with this title <a href='$url' target='_blank'>here</a>. If you have added a duplicate page by mistake please delete this page.", Notice::allowMarkup); } } });
  22. I don't understand what you're saying here or what screenshot you're referring to. But my general point is that fields like Page Reference or Repeater are ultimately about storing a relationship between pages (Repeater items are pages). Rather than use a field to store the relationship, you can use the parent-child relationship. In PW, until pagination support is eventually rolled out to Page-type fields only the parent-child relationship can scale to thousands or millions of pages. But for your case this should be no big problem because the parent-child relationship can achieve what you are doing with the Repeater field. You get a nice sortable paginated list of child pages on the Children tab, and you can customise the page labels in a similar way to the Repeater item labels (see "List of fields to display in the admin Page List" in the Advanced tab of the child template). I would just stick with the Children tab, but if you wanted try more things you could look at Batch Child Editor, or listing child pages using a runtime-only inputfield with modules like this or this, or making use of Lister / Lister Pro to view and filter the child pages.
  23. Personally, I don't allow non-superusers to see the trash and I like that they have to navigate to the Delete tab because I want them to think very carefully before they delete a page. If you want to hide Trash (as per the setting mentioned above) but want to let non-superusers trash pages from Page List then you could look at this module:
  24. FYI, you can disable trash for non-superusers in the ProcessPageList module settings: https://processwire.com/blog/posts/processwire-3.0.107-core-updates/#trash-for-all
  25. I'm not surprised that 1000 repeater items in a field is slow to load. My suggestion is to replace your repeater field with child pages.
×
×
  • Create New...