Leaderboard
Popular Content
Showing content with the highest reputation since 11/23/2025 in all areas
-
Nested Checkboxes An inputfield for Page Reference fields that groups options by their parent page, and optionally by grandparent page too. This can help editors understand the grouping of the selectable pages, and also makes it quicker for an editor to select or unselect an entire group of pages. The checkboxes at the parent and grandparent level are not for storing those pages in the field value - only for quickly selecting or unselecting groups of pages at the lowest level of the hierarchy. For example, in the screen recording above the "Cities" Page Reference field allows only pages with the "city" template, and the pages at the country and continent level are not included in the field value. The inputfield is only for use with Page Reference fields because the structure comes from the page tree. Requires PW >= v3.0.248. Configuration For each field that uses the inputfield you have these options: Checkboxes structure: choose "Parents" or "Parents and grandparents". Collapse sections that contain no checked checkboxes: this option makes the inputfield more compact. There are also the standard column width and column quantity options familiar from the InputfieldCheckboxes inputfield. These apply to the selectable pages at the lowest level of the hierarchy, and the structure is arguably more readable when these are left at their defaults. https://github.com/Toutouwai/InputfieldNestedCheckboxes https://processwire.com/modules/inputfield-nested-checkboxes/17 points
-
This module is nothing special. It adds a small JavaScript and CSS file to your page to create a nice snowfall. To adapt the snowfall to your needs you have some configuration options like snowfall density, min and max size of the snowflakes, duration time of the snowflakes and more. You have the option to start and stop the snowfall manually or depending on the date. At the moment you will find a live example here: https://www.schulfreund.at/ This example is only active in the winter season - not the whole year 😉 You can find the full docs and description and the download possibility of the module here. Have fun and enjoy the winter!!11 points
-
Which CMF does this? It is very challenging to have a default solution for this in the codebase IMHO. This matter becomes more complex depending on the age and size of the website. It may have several repercussions: SEO implications and content considerations, such as: - What if some pages only exist in English? Some sites may have pages with content available only in a secondary language. - What about hardcoded URLs in content (WYSIWYG fields)? - Some business logic checking the language on the templates - Etc.5 points
-
Hooking after that method wasn't as bad as I was thinking, so this is my current quick solution: wire()->addHookAfter('ProcessLogin::buildLoginForm', function(HookEvent $event) { $form = $event->return; $form->get('login_name')->attr('autocomplete', 'off'); $form->get('login_pass')->attr('autocomplete', 'off'); $event->return = $form; });4 points
-
Hi @Sergio, i fully agree, this is tough to achieve. Because of the exceptions. As far as i am told joomla for example supposed to handle this a bit more easy. However they do it, i do not want to use Joomla anyway. Finally i wrote a little script which helps me to swap content. And - important for me - it includes most of the available multilingual field types. For my current project (which triggered the posting) this means i got this default language swapping thing ready in less than 5 hours. Instead of several days. Maybe this is also helpful for others... https://gist.github.com/olafgleba/1e1c33d8ad3fc22961dfba33a6ee2f363 points
-
This week I've added support for File Regions, part of the Markup Regions output system in ProcessWire. File Regions enable you to populate CSS and JS files with Markup Regions. I'm short on time today, so rather than writing much about it here, I've put up a documentation page for it in the API reference, which I'll link below. I'm using File Regions on a project right now and am finding it to very useful. Especially on a project where there are multiple developers, it simplifies a lot to be able to build features as self contained components, while still using the traditional route for site-wide stuff. It's something different, and I'm curious to know what you think. Here's the new documentation page for File Regions below. The page was a bit rushed, so I'll likely be amending it, but hopefully it gets across the main ideas. Thanks for reading and have a great weekend! https://processwire.com/api/ref/wire-markup-file-regions/2 points
-
AgeWire is a powerful, fully customizable age verification module for ProcessWire, built with modern web standards and powered by Tailwind CSS. Perfect for sites requiring age gates (alcohol, tobacco, adult content, etc.). Key Features Two Verification Modes: Simple Yes/No buttons Date Picker with separate MM/DD/YYYY inputs (bot-resistant) 13 Stunning Themes: Modern, Dark, Classic, Minimal, Gradient, Neon, Elegant, Corporate, Vibrant, Nature, Sunset, Ocean, Purple 4 Smooth Animations: Fade In, Slide Up, Zoom In, Bounce In International Date Formats: MM/DD/YYYY (US) DD/MM/YYYY (EU) YYYY/MM/DD (ISO) Advanced Security: Secure, HttpOnly, SameSite cookies Configurable lifetime (1 day to 6 months) Bot protection via manual date entry Smart Exclusions: Skip verification on specific templates or pages Admin pages auto-excluded Privacy & Compliance: Optional Terms & Privacy Policy checkbox Custom links to your legal pages Fully Responsive – Mobile-first design Custom CSS support Tailwind CDN integration (no build required) Installation Download from GitHub Place AgeWire folder in /site/modules/ Go to Modules > Refresh Install AgeWire GitHub: https://github.com/mxmsmnv/AgeWire Download: https://github.com/mxmsmnv/AgeWire/archive/refs/tags/v1.0.9.zip Perfect for: Wineries & breweries Vape & tobacco shops Adult content sites Age-restricted events Feedback, bug reports, and pull requests are welcome! If you like AgeWire, please ⭐ star it on GitHub! Made with ❤️ for the ProcessWire community.2 points
-
@bernhard I completely forgot about this post and ended up with a solution. I do have a default block and did implement this as you described. Interestingly I did this on my own having missed your reply. So we were thinking in the same direction.. This is ultimately what I came up with and this made it much easier to implement a solution and with less effort. This is a simple example of a block with an image marquee. I only want the block to render if there are images that will show up on the page. <?php // rest of block... /** * Renders this block if conditions are met */ public function renderBlock(): string|Html { if ($this->images->count()) { return ''; } parent::renderBlock(); } // rest of block... I added a renderBlock() method that overrides the parent Block::renderBlock(). It contains all of the logic that determines if a block will render. For a complex block that has multiple fields that need to be checked this can be very helpful. It is also very clean and simple since that method is automatically called when RPB renders blocks anyway. I think this is better than an entirely new method like shouldRender() In my case there are blocks which have an ASM page select. The pages that can be selected may become unpublished or hidden which will remove them from the selected pages. If there are no pages left to render then renderBlock() will return an empty string and prevent it from rendering without any need to go through the site and hide blocks that don't have any pages. This allows for dynamic changes in content and the block always behaves as needed. Thank you for working on a solution and apologies that I missed it!1 point
-
@markus-th I checked it out and it works like treat!😀 A huge thank you from Dillingen to Kulmbach!1 point
-
If you dynamically add parameters to your link, you can use them in a hook: $wire->addHookBefore('Pages2Pdf::download', function($event) { /** @var Pages2Pdf $module */ $module = $event->object; $input = $event->wire('input'); $sanitizer = $event->wire('sanitizer'); // 1. Check if we are in your specific scenario // (Optional: limit this to specific templates if needed) $page = $event->arguments(0); if($page->template != 'your-list-template') return; // 2. Retrieve your filter parameters from the URL // Example URL: ?pages2pdf=1&filter_category=music&date=2023 $category = $input->get('filter_category'); $date = $input->get('date'); // 3. Build a safe filename string // It is crucial to sanitize these inputs to avoid invalid filesystem characters $filenameParts = [$page->name]; if($category) { $filenameParts[] = $sanitizer->pageName($category); } if($date) { $filenameParts[] = $sanitizer->pageName($date); } // Add unique ID or timestamp if you want to avoid caching conflicts completely // $filenameParts[] = time(); $newFilename = implode('-', $filenameParts) . '.pdf'; // 4. Overwrite the module setting for this specific request $module->set('filename', $newFilename); }); Important: The hook must be implemented via init.php. It does not work in ready.php. Actually tested it here to add the amount of portions into the filename: https://www.dothiscookingthing.de/rezepte/lachs-spiesse-mit-garnelen-aus-dem-ofen/1 point
-
1 point
-
I also learned that this mostly doesn't matter in modern browsers, since they'll ignore it. But hey, this security scan will pass now! 🤣1 point
-
@Juergen Installed to one of my clients site. He said it is very funny. Thanks for sharing. Gideon1 point
-
Funny, I just implemented almost the same feature as a Hanna Code for a client 😄 <script type="module" src="https://unpkg.com/@le-pepe/snow-effect"></script> <snow-effect flakes="500" color="#e5f5ff"></snow-effect> It seems it’s Christmas time again! 🎄1 point
-
Thanks very much @bernhard I downloaded dev version, replaced in module folder and now all is ok 👍1 point
-
Hello @ all The new version 2.3.0 comes with a brand new feature: the possibility to turn a form into a multi-step form. Many thanks to @Jan S. for the idea and the support in testing during the development of the new feature. In a nutshell: A multi-step form is a long form divided into multiple steps. At the end of each step, the user clicks on a "Next" button to go to the next section. In the final step a summary of the data entered will be displayed to the user. The user now has the option to change some of the data if necessary before finally submitting the form. Typical use cases are very long forms, surveys or quizzes. I have written an extra chapter in the docs with a lot more information, which you can find here. There are only 2 restrictions for multi-step forms to work properly: The send button must be after the last step (by the way, it wouldn't make sense to put it anywhere in between ;-)) File upload fields must be placed in the last step (otherwise they won't work) To turn a form into a multi-step form, you only need one new method: addStep() You need to add this method to the form object in the places where you want to make the cut: $form = new \FrontendForms\Form('simpleform'); $firstname = new \FrontendForms\InputText('firstname'); $firstname->setLabel('Firstname'); $firstname->setRule('required'); $form->add($firstname); $lastname = new \FrontendForms\InputText('lastname'); $lastname->setLabel('Lastname'); $lastname->setRule('required'); $form->add($lastname); $form->addStep(); // first step $email = new \FrontendForms\InputEmail('email'); $email->setLabel('Input Email'); $email->setRule('required'); $form->add($email); $form->addStep(); // second step $birthday = new \FrontendForms\InputDate('date'); $birthday ->setLabel('Birthday'); $form->add($birthday ); $form->addStep(); // third step $message = new \FrontendForms\Textarea('message'); $message->setLabel('My message'); $form->add($message); $form->addStep(); // fourth step $button = new \FrontendForms\Button('submit'); $button->setAttribute('value', 'Send'); $form->add($button); if($form->isValid()){ print_r($form->getValues()); // do what you want } // render the form echo $form->render(); That is all! You can find more examples here. To be informed of all the changes in this release, please read the changelog. As always, please keep an eye on whether everything is working as expected and report any issues you discover here or directly on GitHub. Jürgen1 point
-
My tailwind.dist.css file only contains what my projects need most of the time - on all pages/views/whatever. 😁 So there is that. However you could split it up in several TailwindCSS files. One for only layouts, one for components (or even each component), one for this, and one for that. It depends on how much time you want to invest and break things up into smaller pieces and then add to whereever you finally load the CSS files. I think it's quite a bit of an overhead, but in case your projects are huge or have multiple areas, such as frontend, backend (not ProcessWire itself, but like a custom member area) this could help. First step would be disabling automatic detection - see here: https://tailwindcss.com/docs/detecting-classes-in-source-files#disabling-automatic-detection Then you would need multiple .css files that have directives to source only some parts of your files. It really depends on how well-structured your files are. Also in the docs, see link above. @import "tailwindcss" source(none); @source "../admin"; @source "../shared";1 point
-
Hi everyone, Here's a new module that I have been meaning to build for a long time. http://modules.processwire.com/modules/process-admin-actions/ https://github.com/adrianbj/ProcessAdminActions What does it do? Do you have a bunch of admin snippets laying around, or do you recreate from them from scratch every time you need them, or do you try to find where you saw them in the forums, or on the ProcessWire Recipes site? Admin Actions lets you quickly create actions in the admin that you can use over and over and even make available to your site editors (permissions for each action are assigned to roles separately so you have full control over who has access to which actions). Included Actions It comes bundled with several actions and I will be adding more over time (and hopefully I'll get some PRs from you guys too). You can browse and sort and if you have @tpr's Admin on Steroid's datatables filter feature, you can even filter based on the content of all columns. The headliner action included with the module is: PageTable To RepeaterMatrix which fully converts an existing (and populated) PageTable field to either a Repeater or RepeaterMatrix field. This is a huge timesaver if you have an existing site that makes heavy use of PageTable fields and you would like to give the clients the improved interface of RepeaterMatrix. Copy Content To Other Field This action copies the content from one field to another field on all pages that use the selected template. Copy Field Content To Other Page Copies the content from a field on one page to the same field on another page. Copy Repeater Items To Other Page Add the items from a Repeater field on one page to the same field on another page. Copy Table Field Rows To Other Page Add the rows from a Table field on one page to the same field on another page. Create Users Batcher Allows you to batch create users. This module requires the Email New User module and it should be configured to generate a password automatically. Delete Unused Fields Deletes fields that are not used by any templates. Delete Unused Templates Deletes templates that are not used by any pages. Email Batcher Lets you email multiple addresses at once. Field Set Or Search And Replace Set field values, or search and replace text in field values from a filtered selection of pages and fields. FTP Files to Page Add files/images from a folder to a selected page. Page Active Languages Batcher Lets you enable or disable active status of multiple languages on multiple pages at once. Page Manipulator Uses an InputfieldSelector to query pages and then allows batch actions on the matched pages. Page Table To Repeater Matrix Fully converts an existing (and populated) PageTable field to either a Repeater or RepeaterMatrix field. Template Fields Batcher Lets you add or remove multiple fields from multiple templates at once. Template Roles Batcher Lets you add or remove access permissions, for multiple roles and multiple templates at once. User Roles Permissions Batcher Lets you add or remove permissions for multiple roles, or roles for multiple users at once. Creating a New Action If you create a new action that you think others would find useful, please add it to the actions subfolder of this module and submit a PR. If you think it is only useful for you, place it in /site/templates/AdminActions/ so that it doesn't get lost on module updates. A new action file can be as simple as this: <?php namespace ProcessWire; class UnpublishAboutPage extends ProcessAdminActions { protected function executeAction() { $p = $this->pages->get('/about/'); $p->addStatus(Page::statusUnpublished); $p->save(); return true; } } Each action: class must extend "ProcessAdminActions" and the filename must match the class name and end in ".action.php" like: UnpublishAboutPage.action.php the action method must be: executeAction() As you can see there are only a few lines needed to wrap the actual API call, so it's really worth the small extra effort to make an action. Obviously that example action is not very useful. Here is another more useful one that is included with the module. It includes $description, $notes, and $author variables which are used in the module table selector interface. It also makes use of the defineOptions() method which builds the input fields used to gather the required options before running the action. <?php namespace ProcessWire; class DeleteUnusedFields extends ProcessAdminActions { protected $description = 'Deletes fields that are not used by any templates.'; protected $notes = 'Shows a list of unused fields with checkboxes to select those to delete.'; protected $author = 'Adrian Jones'; protected $authorLinks = array( 'pwforum' => '985-adrian', 'pwdirectory' => 'adrian-jones', 'github' => 'adrianbj', ); protected function defineOptions() { $fieldOptions = array(); foreach($this->fields as $field) { if ($field->flags & Field::flagSystem || $field->flags & Field::flagPermanent) continue; if(count($field->getFieldgroups()) === 0) $fieldOptions[$field->id] = $field->label ? $field->label . ' (' . $field->name . ')' : $field->name; } return array( array( 'name' => 'fields', 'label' => 'Fields', 'description' => 'Select the fields you want to delete', 'notes' => 'Note that all fields listed are not used by any templates and should therefore be safe to delete', 'type' => 'checkboxes', 'options' => $fieldOptions, 'required' => true ) ); } protected function executeAction($options) { $count = 0; foreach($options['fields'] as $field) { $f = $this->fields->get($field); $this->fields->delete($f); $count++; } $this->successMessage = $count . ' field' . _n('', 's', $count) . ' ' . _n('was', 'were', $count) . ' successfully deleted'; return true; } } This defineOptions() method builds input fields that look like this: Finally we use $options array in the executeAction() method to get the values entered into those options fields to run the API script to remove the checked fields. There is one additional method that I didn't outline called: checkRequirements() - you can see it in action in the PageTableToRepeaterMatrix action. You can use this to prevent the action from running if certain requirements are not met. At the end of the executeAction() method you can populate $this->successMessage, or $this->failureMessage which will be returned after the action has finished. Populating options via URL parameters You can also populate the option parameters via URL parameters. You should split multiple values with a “|” character. You can either just pre-populate options: http://mysite.dev/processwire/setup/admin-actions/options?action=TemplateFieldsBatcher&templates=29|56&fields=219&addOrRemove=add or you can execute immediately: http://mysite.dev/processwire/setup/admin-actions/execute?action=TemplateFieldsBatcher&templates=29|56&fields=219&addOrRemove=add Note the “options” vs “execute” as the last path before the parameters. Automatic Backup / Restore Before any action is executed, a full database backup is automatically made. You have a few options to run a restore if needed: Follow the Restore link that is presented after an action completes Use the "Restore" submenu: Setup > Admin Actions > Restore Move the restoredb.php file from the /site/assets/cache/AdminActions/ folder to the root of your site and load in the browser Manually restore using the AdminActionsBackup.sql file in the /site/assets/cache/AdminActions/ folder I think all these features make it very easy to create custom admin data manipulation methods that can be shared with others and executed using a simple interface without needing to build a full Process Module custom interface from scratch. I also hope it will reduce the barriers for new ProcessWire users to create custom admin functionality. Please let me know what you think, especially if you have ideas for improving the interface, or the way actions are defined.1 point
-
I don't want to be too blunt and I can't speak for anyone else, but I've never referred a client to a software or service website as part of the education process. It doesn't do anything for them. You are the expert. The person making the pitch should be able to fully explain the technology stack to the extent that the conversation requires it in language they can understand because we are the interpreters. Clients trust me because I am the expert and the top 3 things they care about are these, in this order: How much is this going to cost me? Why don't we use xxx? (or, our current site is xxx I'm not sure we want to switch) When is it going to be done? Sending a client to any site for tools or software is like saying "here, do your own research". The ProcessWire site, like any other development tools/software sites, isn't there to woo clients. Most clients don't care enough to take time and truly understand it because that's not their job. If a curious client is in a position to go to websites like ProcessWire, several steps have been skipped in the client discovery/planning process IMHO. I'd even go so far as to say that if a site has "Docs" or "Documentation" in the primary nav, it's not for clients and they shouldn't be there. I hope this isn't a too hot a take... I would say that improvements could be made iteratively with more use of color for contrast, emphasis, and indicating priority. I think it's a flexible design that can evolve in whatever capacity that may be needed. This has the ability to highlight some impressive facts and figures. No notes on the content, some elements could be integrated into the current design. Even then, facts and figures are for devs. I used the word "scalability" with a manager once and they stopped the conversation to ask "wait, what does that mean?" and still didn't care when I explained. A a CMS or framework site is never going to lead to clients translating what's on the page to time or money. In all likelihood, the conversation you are having with a client at 10:00 just followed a call with their product distributor at 8:00am, their accountant at 9:00, and at 11:00 they're meeting with other members in management. Personally, I would no sooner send someone to processwire.com than I would laravel.com. You are the time and money. I agree with this. I will go out on a limb and say the number of end customers who went to the Drupal site and left thinking they need a Drupal site isn't zero, but it's probably close. If someone is hiring a Drupal developer then they're in a role where it's part of their job to understand the tech stack even if they aren't a dev. Visiting wordpress.com, it doesn't target the end user but name recognition still draws business which overcomes the website entirely. This is fair. It doesn't take a monitor that computer professionals use to get this experience. All you need is a consumer iMac. I think iteration can address concerns. I don't want to belabor the point, but to be fair, did you ever send a client to the QuarkXpress website... Just a little joke ☺️ Cheers from a fellow old school developer who built their first website in 1997 and tinkered with QuarkXpress 🍻1 point
-
I disagree. As a designer and developer, I think the new design is much more professional, contemporary, and appropriate. Compare it to the Dupal or WordPress website. Do you think they are better positioned? What information do you think is missing for customers?1 point
-
Hello again! The new AppApi release v1.4.0 is live now! Changes in 1.4.0 (2025-11-01) Add compatibility for ProcessWire instances installed in a subdirectory (Thank you @saerus for mentioning this issue) Add helper functions that can manipulate subdirectory links. -> Can be very handy for using ProcessWire as a headless CMS for your JavaScript applications (See FAQ for more information) Add config param to disable automatic adding access control headers (Thank you @gerritvanaaken for the ticket) Fix an issue where adding trailing slashes automatically lead to problems with route parameters (Thank you @gingebaker for the ticket) Thank you all for using AppApi, leaving feedback and for posting Github Issues and PRs. Thanks to you, the module keeps getting better and better.1 point
-
Today there’s a new version of ProCache (4.0.7) available for download in the ProCache support/upgrades board. Here’s what’s new in this version of ProCache: ProCache has been updated throughout for PHP 8.4 support. Upgraded the SCSS compiler to the latest Leafo SCSSPHP 2.0.1. This version requires PHP 8.2, so ProCache also lets you choose from two older versions if you prefer. Upgraded the LESS compiler to the latest Wikimedia LESS 5.4.1. Past versions can also be selected, including Wikimedia 3.0.0 and Leafo LESS 0.5.0. Upgraded the CSS/JS minifier to the latest available version (1.3.75 latest). Because we had customized the CSS/JS minification quite a bit, the older version (1.0 stable) also remains selectable, just in case there’s anything the older version handles that the new one doesn’t yet. LESS, SCSS and Minifier versions can be selected and changed in the ProCache configuration: Setup > ProCache > JS/CSS. Likewise the ProcessProCache module has a new JS/CSS tab for configuring the settings mentioned above. ProCache now logs LESS/SCSS and Minify status and errors to the JS console (when in debug mode or for a logged-in superuser). ProCache now has a proper API reference page available here: https://processwire.com/api/ref/pro-cache/ Because this is a brand new version with several upgraded libraries, it should be considered beta until it's been out a couple of weeks. Thanks for reading and have a great weekend!1 point
-
Last week I was on a boat, far from any computer, so that’s why there weren’t any updates. This week I’m back in the office and back to work on the core. The focus has been primarily on optimizations and issue fixes (see dev branch commit log). There were also a couple commits related to PHP 8.4 support. Issue fixes and optimizations will likely continue to get more focus as we get closer to our next main/master version.There are also some Pro module updates in the works as well. Have a great weekend!1 point
-
Correct. My code is wrong. I was searching for this answer today and didn't even remember I'd written this. I have revised my answer just now: // Add these lines to your config.php file. // Tell PHP to use this timezone as the default when a timezone API call doesn't specify a zone. // Change to your local time zone name: https://www.php.net/manual/en/timezones.php date_default_timezone_set('America/New_York'); // Initialize database connection with session time zone based on PHP's time zone. $config->dbInitCommand = (function() { $charset = 'utf8'; // What is the timezone offset (in minutes) from UTC for the current time in the current timezone? $minutes = (new \DateTime())->getOffset() / 60; $sign = ($minutes >= 0) ? '+' : '-'; $h = str_pad(intdiv(abs($minutes), 60), 2, '0', STR_PAD_LEFT); $m = str_pad(abs($minutes) % 60, 2, '0', STR_PAD_LEFT); $dbTimeZone = "{$sign}{$h}:{$m}"; return "SET NAMES '{$charset}', time_zone = '{$dbTimeZone}'"; })(); // Tell ProcessWire to use this timezone. // (You'll find this in your config file already under the comment "Installer: Time zone setting".) $config->timezone = 'America/New_York';1 point
-
Limited Module Edit Allows non-superusers to edit a limited selection of modules. Of course, there are good reasons why non-superusers are normally not allowed to access the configuration screen of modules so use this module with caution. Usage 1. Install Limited Module Edit. 2. In the module configuration select one or more modules in the "Modules enabled for limited editing" field. When you enable a module here a corresponding "lme" permission is installed. For example, if WireMailSmtp is enabled here then a permissioned named "lme-wire-mail-smtp" will be installed. 3. For any role that you want to allow to configure the previously selected modules, enable the "module-admin" permission and the "lme" permissions for any module they may configure. 4. Users with these permissions will now see a special Modules section in the main menu that provides links to configure only the modules they have been given permission for. These users are not allowed to install modules nor are they allowed to uninstall the modules they have permission to configure. https://github.com/Toutouwai/LimitedModuleEdit https://processwire.com/modules/limited-module-edit/1 point
-
1 point
-
After some tedious experiments, I finally managed to switch my site's default language from English to German both in frontend and backend. I am reliefed but not satisfied because it was a terrible hack: Starting with @mscore's SQL script, I added a condition to make sure that field texts are only swapped if a translation exists SET s1.data = s1.data123, s1.data123 = s2.data WHERE s1.pages_id = s2.pages_id AND s1.data1019 != ''; Especially important for backend field without translation, otherwise the backend text will get broken. Then, I added some lines in order to update the option names for FieldtypeOptions: UPDATE fieldtype_options s1, fieldtype_options s2 SET s1.title = s1.title123, s1.title123 = s2.title, s1.value = s1.value123, s1.value123 = s2.value WHERE s1.fields_id = s2.fields_id and s1.option_id = s2.option_id; The following statements are necessary for keeping the correct translation files for both languages (let 124 be the page id of the default language): update field_language_files set pages_id = 123 where pages_id = 124; update field_language_files_site set pages_id = 123 where pages_id = 124; Unfortunately, since translation files are stored in the assets, it is also necessary to swap the corresponding asset directory names: files/123 to files/124. The final step is changing the title of the new non-default language ("deutsch" to "english") and the language names respective. I can't understand why there's still no out-of-the-box solution for this use-case, which is IMHO not so unusual. I also would prefer a PW API solution like @gebeer's one, but I couldnt' find out how to iterate over really all stuff I need (including backend) ...1 point
-
Actually class_exists() should work, but WillyC missed an important part. ProcessWire doesn't include module files that aren't autoload unless some information about them is requested, like $modules->getModuleInfo("className"), or the like. In the same manner, a class_exists("className"); call triggers the autoload mechanism and causes the file to be loaded. But you can prevent that by specifying false as argument 2 to class_exists(): if(!class_exists("ModuleName", false)) { // module is not loaded }1 point
-
Hi Roope Always use: $selectorString = $sanitizer->selectorValue($stringWithCommas); Pw sanitizes the selector string e.g. quotes it when there are commas present.1 point