Jump to content

Leaderboard

Popular Content

Showing content with the highest reputation on 02/19/2026 in all areas

  1. We use the StripePaymentLinks module for all projects where a few products or services are sold on landing pages. Typically, these are NOT shops, and do not require a shopping basket. Cross-selling can be implemented directly with Stripe, and the module also covers this. For shop functionality, when needed, we use whatever fits best. RockCommerce, for example, is elegant and can be set up in no time. So you just need to ask yourself: Do I want my customers to be able to buy more than ONE product at the SAME TIME? Cheers, Mike
    2 points
  2. As long as the output formatting is on you can assume your "$page->title" will return a formatted value and so in your case with the entities encoded thanks to the Textformatter. So no need to escape it again using $sanitizer. $sanitizer is mostly here to clean inputs from user-submitted forms or more broadly whenever you have to save external data you don't have control over.
    2 points
  3. I second this wholeheartedly. The community is among the very best out there, and the lack of opinion, the clear structure and the ease of extending make PW a wonderful tool. It's a sad fact that my days of working with ProcessWire are mostly over. My job responsibilities have changed over time, and the demand for wholly integrated cloud systems led my employer to migrate our intranet site with tens of thousands of pages and a lot of advanced functionality to another platform (let's not talk about the manpower needed to do that and the gaps left). There are of course advantages, but I can say that we had a tailored-to-fit solution on a level you don't find often, from ordering breakfast or lunch from local suppliers, over advanced forms connected to HR systems and Active Directory data, providing specialized integrated databases and automated workflows to our departments, to driving technical sales with dynamically generated interlinked views on bills of material, stocks and data sheets pulled directly from SAP. A piece of software more than 60% of 1300 worldwide employees used daily and that ran with 100.0% availability on a single IIS server with only a bit of memcache magic to keep things speedy. Over more than ten years, periodic updates went through with nary a hitch. My heart bleeds a bit. Not working with PW every week also means that I'm not actively using the modules I built anymore. I'll have to go over my little babies one by one, retire those that have been surpassed by better approaches by now and find new pet owners for the others.
    2 points
  4. Thanks! All of them are built using ProcessWire, it's my tool of choice ever since I got introduced to it close to 10 years ago 🙂
    1 point
  5. This is a module I made as an experiment a while ago and never got around to releasing publicly. At the time it was prompted by discussions around using Repeater fields for "page builder" purposes, where the depth feature could possibly be used for elements that would be nested inside other elements. I thought it would be useful to enforce some depth rules and translate the depth data into a multi-dimensional array structure. I'm not using this module anywhere myself but maybe it's useful to somebody. Repeater Depth Helper This module does two things relating to Repeater fields that have the "Item depth" option enabled: It enforces some depth rules for Repeater fields on save. Those rules are: The first item must have a depth of zero. Each item depth must not be more than one greater than previous item depth. It provides a RepeaterPageArray::getDepthStructure helper method that returns a nested depth structure for a Repeater field value. Helper method The module adds a RepeaterPageArray::getDepthStructure method that returns a multi-dimensional array where the key is the page ID and the value is an array of nested "child" items, or null if there are no nested children. Example The module doesn't make any assumptions about how you might want to use the depth structure array, but here is a way you might use it to output a nested unordered list. // Output a nested unordered list from a depth structure array function outputNestedList($depth_structure, $repeater_items) { $out = "<ul>"; foreach($depth_structure as $page_id => $nested_children) { $out .= "<li>" . $repeater_items->get("id=$page_id")->title; // Go recursive if there are nested children if(is_array($nested_children)) $out .= outputNestedList($nested_children, $repeater_items); $out .= "</li>"; } $out .= "</ul>"; return $out; } $repeater_items = $page->my_repeater; $depth_structure = $repeater_items->getDepthStructure(); echo outputNestedList($depth_structure, $repeater_items); https://github.com/Toutouwai/RepeaterDepthHelper https://modules.processwire.com/modules/repeater-depth-helper/
    1 point
  6. Thanks again @monollonom. That helps a lot. Still trying to scope out what output stategy is best for a portfolio site I've built as static html, with possible a small store at a future date. I would like to ensure my GSAP scroll animations work properly so controlling JS and CSS from one working base seems better than using lots of include templates, Idk... Rather new to this. By the way, I had a look at your site. Your work is very impressive, well done. Did you build any of those sites with ProcessWire by any chance?
    1 point
  7. I have never been loyal to tools for the sake of it. If something stops earning its keep, I move on. The reason I have stayed with ProcessWire for close to ten years is simple: it continues to make sense for how I work. I still look after sites I built many years ago, and most of them just run. No rewrites, no upgrade stress, no feeling that past work is a liability. The API has stayed stable, and when it has changed, it has been deliberate and predictable. That matters when you are responsible for client sites long-term. What really locked me in early on was the front-end freedom. PW never told me how a site should look or behave. It gave me solid building blocks and allowed me to choose. I can build very different sites without switching platforms or fighting opinionated defaults, and that freedom is something I value. The forum is another reason I am still here. You, the people in this community, take the time to understand a problem before jumping to solutions. That is very rare. The discussions are thoughtful, practical, and grounded in real experience, and I have learned a lot simply by reading how others approach things. And finally, trust. I trust ProcessWire not to chase trends simply for attention, and not to trade clarity or performance for fashion. Ten years on, it still feels like a system built by people who actually build websites. For me, that combination has been hard to beat.
    1 point
  8. Generates a .phpstorm.meta.php file for ProcessWire autocompletion in PhpStorm. Features Autocomplete wire container keys for wire('...') and Wire::wire('...') Autocomplete module names for Modules::get() and Modules::install() Autocomplete field names for Fields::get() Autocomplete template names for Templates::get() Autocomplete unique page names for Pages::get() Autocomplete hookable methods for Wire::addHook*() Autocomplete page status constants/strings for Page::status(), addStatus(), removeStatus(), hasStatus() Autocomplete field flags for Field::addFlag(), removeFlag(), hasFlag() Autocomplete template cache-expire constants for Template::cacheExpire() Autocomplete Inputfield collapsed constants for Inputfield::collapsed() Autocomplete sort flags for WireArray::sort()/sortFlags()/unique() and PageArray::sort()/sortFlags()/unique() Optional: Field type autocompletion per Page class (when enabled in module config) Usage Default path: site/assets/.phpstorm.meta.php (configurable in module settings). The file regenerates automatically when fields, templates, or modules change (debounced). You can manually regenerate from the module settings screen. Optional: enable "Generate page-class field metadata" in module settings for field type hints per Page class. This is intentionally basic. For richer field stubs, use AutoTemplateStubs. Examples Modules $tracy = $modules->get('TracyDebugger'); // Autocomplete + correct class type for navigation and code insight Wire Container $page = wire('page'); $pages = $this->wire('pages'); $cache = wire('cache'); // Autocomplete for keys like page/pages/cache/etc. Fields $body = $fields->get('body'); // Autocomplete field names, fewer typos Templates $tpl = $templates->get('basic-page'); // Autocomplete template names Pages $home = $pages->get('/'); // Maps to the page class when page classes are enabled Page Status $page->status(Page::statusHidden); $page->addStatus('draft'); $page->removeStatus(Page::statusUnpublished); $page->hasStatus('locked'); Field Flags $field->addFlag(Field::flagAutojoin); $field->removeFlag(Field::flagAccess); $field->hasFlag(Field::flagGlobal); Template Cache Expire $template->cacheExpire(Template::cacheExpireParents); Inputfield Collapsed $inputfield->collapsed(Inputfield::collapsedYesAjax); Sort Flags $items->sort('title', SORT_NATURAL | SORT_FLAG_CASE); $items->sortFlags(SORT_NATURAL); $items->unique(SORT_STRING); Page-Class Field Metadata (Optional) $home = $pages->get('/'); // $home is HomePage (page class) // Field types are inferred from the template fieldgroup // e.g. $home->hero_image -> Pageimage or Pageimages depending on field settings Hooks $wire->addHookAfter('Pages::save', function($event) { // Autocomplete hookable methods while typing the hook string }); Notes Hook scanning reads ProcessWire core, modules, and admin templates to build the hook list. If page classes are enabled, page names map to their page class; otherwise they map to Page. Improvement suggestions and PRs are welcome. https://github.com/phlppschrr/ProcessWirePhpStormMeta
    1 point
  9. The update to Processwire 255 master still does not work, even not with 2000 files...
    1 point
  10. AltTextGpt for ProcessWire This ProcessWire module, AltTextGPT, is an interface for generating alt text for all of the images in your website, using the ChatGPT Open AI API. Using the API requires an account with the Open AI API and costs money, although its pay-what-you-use and the charges are minimal. For example, alt text was generated for 200 images, using 94 cents of Open AI Credits. You can create an account with Open AI, from this link, and then once you have an API key, you can enter it below, or configure it as a permanent setting for this module via Modules->Configure->AltTextGpt. After configuring the API key as described above, you can then use the form below to generate alt text for images in the site. The module will attempt to generate alt txt for every image that currently has no alt text, one at a time. Generating alt text takes a few seconds for each image, so this is not an instantaneous process. For this reason, if you have many images, we suggest generating alt text for the images in batches. You can also set a batch size below, generating alt text for 10 or 20 images at a time, and then repeating the process, until you have generated alt text for all of the images in the site. After each run, the table above should show that there are fewer images without alt text in the site, until eventually the table indicates that there are 0 images in the site without alt text. Note, for alt text to show up for images uploaded in the body of a CKEditor field, this configuration must be set for that field as described in this comment. How to install this module Copy all of the module files to /site/modules/AltTextGpt/. In your admin, go to Modules > Refresh. Click “Install” for the “AltTextGpt” module (on the “Site” tab). The code for the module is tested and working and is currently here: https://github.com/mhfowler/AltTextGpt
    1 point
×
×
  • Create New...