Jump to content

Robin S

Members
  • Posts

    4,928
  • Joined

  • Days Won

    321

Everything posted by Robin S

  1. I'm reluctant to do that because the presence of the Hanna Code textformatter is how the module knows whether it should be interfering with the CKEditor field by loading plugins that will widgetise strings surrounded by the Hanna Code delimiters. Although it wouldn't be a common scenario, it ought to be possible for someone to use the Hanna Code delimiters for some other purpose within a field that isn't configured for Hanna Code without Hanna Code Dialog messing with it. You situation sounds like a fringe case. If the objective is to use unformatted field content in the repeater label could you use a hook instead? E.g. $wire->addHookAfter('InputfieldRepeater::renderRepeaterLabel', function (HookEvent $event) { $page = $event->arguments(2); $inputfield = $event->object; $field = $inputfield->hasField; if($field->name !== 'your_repeater') return; $label = strip_tags($event->wire()->sanitizer->truncate($page->getUnformatted('body'), ['maxLength' => 100, 'more' => ''])); $event->return = $label; });
  2. I tested with the latest dev and latest version of the module but I can't reproduce that. The dropdown appears for CKEditor fields where it is added to the toolbar, inside a repeater or nested repeater. Let me know if you can give me any more tips for how to reproduce, thanks.
  3. Besides @adrian's suggestion, here is another way: $width = $page->fields->getField('myfield', true)->columnWidth;
  4. You'll need to use a hook for this rather than the access settings in the template. Give the role view and edit access in the template settings and add the following in /site/init.php $wire->addHookAfter('Page::viewable, Page::editable', function(HookEvent $event) { $page = $event->object; $user = $event->wire()->user; // Only for non-superusers, for a specific template if($user->isSuperuser() || $page->template != 'restrict_files') return; // Adjust to suit your template name // User may only view or edit page if they created it $event->return = $page->created_users_id === $user->id; });
  5. Oh, right. Then the other thing to check is that the guest role does not have view access for the template. The notes for the "Prevent direct access to file assets" setting explain that this option means that files have the same access as the page that owns them. So if you want to deny file access to guests (or any other role besides superuser) then you must deny view access to the template for that role.
  6. Are you testing this as a non-logged-in user, e.g. in an incognito window? The superuser is never restricted so if you are testing as a superuser then PW is going to serve you the file no matter what. Don't include the hyphen in the URL. The correct URL in this case would be http://localhost:8080/site/assets/files/1030/test.pdf. The point is that direct access to the file at its actual location is forbidden, and instead PHP will grant or block access to the file depending on if the user is allowed.
  7. Markup Regions work by having markup appear before the opening <html> tag. Reference: https://processwire.com/docs/front-end/output/markup-regions/#technical-details-of-how-markup-regions-work So when hooking TemplateFile::render you would insert the HTML that will populate a Markup Region at the start of the rendered template file output, so it will appear before the contents of the auto-appended _main.php. Example: $wire->addHookAfter('TemplateFile::render', function(HookEvent $event) { $template_file = $event->object; $out = $event->return; // If the template file being rendered is basic_page.php... if($template_file->filename === $event->wire()->config->paths->templates . 'basic_page.php') { // ...then prepend the following Markup Region markup $my_region = <<<EOT <div id="body"> <p>Hello world</p> </div><!--#body--> EOT; $event->return = $my_region . $out; } });
  8. 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... } });
  9. 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.
  10. 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>"; }
  11. 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/
  12. 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); } } } });
  13. You can use the API for this - covered in this post:
  14. 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); });
  15. 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; });
  16. There's a module for that: https://modules.processwire.com/modules/template-tags-edit-list/
  17. 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, '|');
  18. @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.
  19. @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!
  20. "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.
  21. 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.
  22. 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; } });
×
×
  • Create New...