-
Posts
5,045 -
Joined
-
Days Won
340
Robin S last won the day on December 21 2025
Robin S had the most liked content!
Profile Information
-
Gender
Male
-
Location
New Zealand
Recent Profile Visitors
The recent visitors block is disabled and is not being shown to other users.
Robin S's Achievements
-
Fantastic! I'll be using this a lot. Thanks @adrian
-
Cool, thanks.
-
Yeah, I've mostly weaned my sites off of it, but I have a few busy ones where I don't want to force the logout of all the front-end users. After upgrading the "Running..." notice just keeps going, and when I checked the browser console there was an error message.
-
Thanks @adrian, working great now. Yes, love this feature here, and in the Tracy Console too. Thanks for adding it!
-
Hi @adrian, I have an action that was working in v0.9.8 <?php namespace ProcessWire; class DownloadModulesDirectory extends ProcessAdminActions { protected $title = 'Download modules directory'; protected $description = 'Download a ZIP file of /site/modules/'; protected $author = 'Robin'; protected $dbBackup = 'disabled'; protected function defineOptions() { return array(); } protected function executeAction($options) { $files = $this->wire('files'); $config = $this->wire('config'); $zip_pathname = $config->paths->site . 'modules.zip'; $files->zip($zip_pathname, $config->paths->siteModules, ['overwrite' => true]); $files->send($zip_pathname); return true; } } In v1.0.1 the zip is created but a download isn't prompted, and I see this when executing the action:
-
Hi @adrian, I also got the CSRF issue when using the console. I think it's a compatibility issue with SessionHandlerDB. The console works when that module is uninstalled.
-
@Marty Walker, I don't want to complicate what this module does, but you can achieve your objective with a bit of custom JavaScript added to the PW admin. Custom JavaScript file in /site/templates/scripts/admin-custom.js $(function() { // Copy a string to the clipboard function copyToClipboard(string) { // HTTPS websites if(navigator && navigator.clipboard && navigator.clipboard.writeText) { const clipboardItem = new ClipboardItem({ 'text/html': new Blob([string], {type: 'text/html'}), 'text/plain': new Blob([string], {type: 'text/plain'}) }); navigator.clipboard.write([clipboardItem]); } // Old browsers or non-HTTPS websites else { const $input = $('<input type="text" value="' + string + '">'); $('body').append($input); $input.select(); document.execCommand('copy'); $input.remove(); } } // When an image thumbnail is Alt-clicked, copy the URL of the corresponding original image document.addEventListener('click', function(event) { if(event.altKey) { const $el = $(event.target.closest('.gridImage__edit, .gridImage__overflow')); if($el.length) { // Prevent any other click handlers from running event.stopImmediatePropagation(); event.preventDefault(); // Copy the image URL const $img = $el.closest('.gridImage').find('img'); const url = window.location.origin + $img.data('original'); copyToClipboard(url); // Highlight the clicked element to show that something happened $el.effect('highlight', {}, 500); } } }, true); }); Add the custom JS file to the PW admin by adding the following line to /site/templates/admin.php ... $config->scripts->add($config->versionUrl($config->urls->templates . 'scripts/admin-custom.js', true)); ...immediately before the existing line... require($config->paths->core . "admin.php"); Now when you Alt-click an image thumbnail the URL of the corresponding original image will be copied to the clipboard.
-
selector: get pages filtered by date weekday
Robin S replied to SebastianP's topic in API & Templates
You would need to use an SQL query to first get the IDs of matching pages, then use those IDs in a PW selector. MySQL has a DAYOFWEEK() function but it starts the numbering on Sunday which is easy to forget. So probably better to use the DAYNAME() function instead. // Get the IDs of all pages where the day name of the date value is Monday $fieldName = 'event_date'; // The name of your date field $tableName = "field_$fieldName"; // The table name is the field name prefixed with "field_" $weekday = 'Monday'; // The day of the week you want to match $stmt = $database->prepare("SELECT pages_id from $tableName WHERE DAYNAME(data) = :weekday"); $stmt->bindValue(':weekday', $weekday); $stmt->execute(); $ids = $stmt->fetchAll(\PDO::FETCH_COLUMN); $idsStr = implode('|', $ids); // Find PW pages $items = $pages->find("template=event, id=$idsStr"); -
Some site-wide JS? // Get the current URL const currentUrl = window.location.href; // Convert to lowercase const lowercaseUrl = currentUrl.toLowerCase(); // Only update if there are uppercase letters if(currentUrl !== lowercaseUrl) { // Use replaceState to update URL without reloading the page window.history.replaceState(null, '', lowercaseUrl); }
- 1 reply
-
- 1
-
-
Thanks @ukyo. I'm now thinking that the module itself should remove the XML declaration when setting the svg property in the formatted value, seeing as the most likely use would be for inline SVG. Do you agree? If so I'll release an update.
-
@d'Hinnisdaël, I was curious about organising a PageArray into a hierarchy, so here is some hook code for modifying a normal InputfieldCheckboxes (when used with a Page Reference field) that you could experiment with. $wire->addHookBefore('InputfieldCheckboxes::render', function(HookEvent $event) { /** @var InputfieldCheckboxes */ $inputfield = $event->object; $field = $inputfield->hasField; if(!$field || $field->name !== 'YOUR_FIELD_NAME') return; function buildHierarchy($pagearray) { // Organise pages by their parent ID and collect all IDs $grouped = []; $itemsById = []; $allIds = []; foreach($pagearray as $page) { $itemsById[$page->id] = $page; $allIds[$page->id] = true; $grouped[$page->parent->id][] = $page; } // Find orphaned parents - parent IDs that don't exist in the PageArray $orphanedParents = []; foreach($grouped as $parentId => $items) { if($parentId !== null && !isset($allIds[$parentId])) { $orphanedParents[] = $parentId; } } // Recursive function to build children function buildChildren($parentId, &$grouped, &$itemsById) { if(!isset($grouped[$parentId])) { return []; } $children = []; foreach($grouped[$parentId] as $item) { $node = clone $item; // Not using "children" as the property name here to avoid clashing with native property $node->nodeChildren = buildChildren($item->id, $grouped, $itemsById); $children[] = $node; } return $children; } // Build trees for all orphaned parents $hierarchy = []; foreach($orphanedParents as $parentId) { $hierarchy = array_merge($hierarchy, buildChildren($parentId, $grouped, $itemsById)); } return $hierarchy; } function renderCheckboxesList($items, $inputfield) { $out = "<div class='nested-checkboxes-list'>"; foreach($items as $item) { $label = $item->getFormatted('title'); $checked = ''; if($inputfield->isOptionSelected($item->id)) $checked = " checked='checked'"; $out .= "<div class='nested-checkboxes-item'><label><input$checked type='checkbox' name='{$inputfield->name}[]' value='{$item->id}' class='uk-checkbox'><span class='pw-no-select'>$label</span></label>"; if($item->nodeChildren) $out .= renderCheckboxesList($item->nodeChildren, $inputfield); $out .= "</div>"; } $out .= "</div>"; return $out; } $options = $inputfield->getOptions(); $optionIdsString = implode('|', array_keys($options)); $selectable = $event->wire()->pages->find("id=$optionIdsString, sort=parent.sort, sort=sort"); $hierarchy = buildHierarchy($selectable); $out = renderCheckboxesList($hierarchy, $inputfield); $out .= <<<EOT <style> .nested-checkboxes-list:not(.InputfieldCheckboxes > .nested-checkboxes-list) { padding-left:25px; } .nested-checkboxes-item input { margin-right:0.5em; } </style> EOT; $event->replace = true; $event->return = $out; }); Before: After: There's no JavaScript (I'll leave that to you), but in any case you would likely need to use PHP logic to set the selection state of parent items on Pages::saveReady() or else the field value would get out of whack any time an option was set via the API rather than via the inputfield. That's why having the parents/grandparents in the field value is something that can't really be handled by a module that is an inputfield only and is probably best done in custom code that's specific to your project.
- 6 replies
-
- 1
-
-
- inputfield
- checkboxes
-
(and 2 more)
Tagged with:
-
Thanks! Sorry, no, the exclusion of the grandparents and parents from the Page Reference field value is baked in. What you're describing would need to be handled by a different module.
- 6 replies
-
- inputfield
- checkboxes
-
(and 2 more)
Tagged with:
-
@ryan, could you please take another look at this breaking change before releasing the next master: https://github.com/processwire/processwire-issues/issues/2157 I have modules that break when updating to the most recent PW version.
- 1 reply
-
- 7
-
-
-
Iconify Icon A bundle of fieldtype, inputfield, and admin helper modules for searching and displaying Iconify icons. Over 200,000 open source vector icons are available for selection. Requires the FileValidatorSvgSanitizer module. Be sure to abide by the license terms of any icons you use. The license of each icon set is viewable on the Iconify website. Fieldtype and inputfield modules When the FieldtypeIconifyIcon and InputfieldIconifyIcon modules are installed you can create a field of type IconifyIcon. Field config options Iconify icon set prefixes: In most cases you will want to define one or more icon set prefixes for the field, to limit the search to those particular icon sets. This is because the number of icons available through Iconify vastly exceeds the maximum of 999 results that can be returned via the Iconify search API. You can find the prefix of an icon set from its URL by browsing at https://icon-sets.iconify.design/. For example, the prefix of the icon set browsable at https://icon-sets.iconify.design/mdi/ is "mdi". Enter the icon set prefixes into the config field separated by commas. Icon preview size: Enter a width/height in pixels for the preview of the selected icon if you want to override the default. Using the inputfield Type an icon name (or part of an icon name) into the search input and a list of matching icons will be displayed. You can hover on an icon in the results to see the set prefix and name of the icon. Click on an icon to select it. If you have not defined any icon set prefixes in the field config then you can limit the search to particular icon sets by entering icon set prefixes into the search input before a colon. For example, entering "mingcute,tabler:flower" would search for icons with "flower" in their name from the "mingcute" and "tabler" icon sets. When the page is saved the selected icon is downloaded from Iconify, sanitized via the FileValidatorSvgSanitizer module, and stored within the /site/assets/iconify/ directory. Icons are not automatically deleted from this directory if they are no longer used in a page value, but if you want to clean up this directory at any point you can delete it and icons will be automatically re-downloaded when they are next needed. The field value The formatted value of a IconifyIcon field is a WireData object with the following properties: set: The icon set prefix name: The icon name path: The path to the icon file url: The URL to the icon file svg: The SVG code of the icon raw: The raw icon value that is stored in the database For example, if your icon field was named "icon" and you were outputting the src attribute of an <img> tag, you would use $page->icon->url. Or if you were outputting inline SVG code you would use $page->icon->svg. The unformatted value of a IconifyIcon field is the raw database value. Normally you won't need to deal with the raw value when using the inputfield, but if you want to use the API to set a field value then the format of the raw value is iconify--[icon set prefix]--[icon name]. Example: iconify--mingcute--flower-line. Example of object properties: Using Iconify icons in the ProcessWire admin Installing the AdminIconifyIcon module allows you to use Iconify icons as field, template or page icons in the ProcessWire admin. Icons used in the ProcessWire admin are monochrome so any colours or shades in selected icons will not be preserved. Module config You can define icon set prefixes and the icon preview size in the module config. These settings are applied to the inputfields used to set Iconify icons for fields and templates. Field and template icons An "Iconify icon" field is added to the Edit Field and Edit Template screens. When this field is populated it overrides any selection in the core "Icon" field and this field is hidden. Page icons To use an Iconify icon as a page icon for admin pages in the ProcessWire menus, create a IconifyIcon field named "page_icon" and add it to the "admin" system template. For any page using the admin template (e.g. a page representing a Lister Pro instance), open it in Page Edit and select an icon in the "page_icon" field. An example of a "Countries" Lister Pro instance with an Iconify icon: https://github.com/Toutouwai/FieldtypeIconifyIcon https://processwire.com/modules/fieldtype-iconify-icon/
-
@Kiwi Chris, check that you are loading your URL segment with a trailing slash. If you're using the "nav" item in the module info your URLs should have the trailing slash like shown the ProcessHello demo module: https://github.com/ryancramerdesign/ProcessHello/blob/189029f494870760107d8a621dfb5a59db53959c/ProcessHello.info.php#L55-L77