Jump to content

Leaderboard

Popular Content

Showing content with the highest reputation on 06/24/2025 in all areas

  1. NOTE: Here and elsewhere referencing ProcessWire Commerce, Padloper refers to Padloper 2. Padloper 1 was retired 3 years ago. -------------- New Site Install ProcessWire Commerce. The current (outdated and incomplete!) Padloper docs are still helpful. Note though that configuring ProcessWire Commerce is accessed via /admin/shop/configure-pwcommerce/. For template files and hooks, please note the following: Changes Template Files All instances of $padloper should be replaced by $pwcommerce. For instance $padloper->getCart() should become $pwcommerce->getCart(). All instances of 'pad_' should be replaced by 'pwcommerce_'. For instance 'pad_price_total' should become 'pwcommerce_price_total'. Hooks Your hooks, e.g. in ready.php should be renamed as follows: All instances of Padloper::someHookedMethod should become PwCommerce::someHookedMethod. Please note the spelling is case-sensitive. Existing Site DO NOT UNINSTALL Padloper! DO NOT INSTALL ProcessWire Commerce! Download and install the Padloper to ProcessWire Commerce migration tool from this repo. Please READ all the instructions! Template Files: As above. Hooks: As above. Any issues please let us know below. Include info about: ProcessWire version (please note ProcessWire Commerce/Padloper's admin GUI is broken in new admin theme, i.e., ProcessWire 3.0.248 (or newer). Padloper version. Site language(s). PHP version. MySQL version. For issues with the migration tool itself, please raise an issue in the project repo. Include the above environment information please. Whilst I have thoroughly tested the migration tool (on a multilingual site), usage of the migration tool is at your own risk!
    2 points
  2. ProcessWire Commerce will be here later today. As mentioned in earlier discussions, my hope is that this will very much become a community project. ProcessWire Commerce is a mature project that powers hundreds of shops, big and small. There still some work needed to make it better. This is where you can chime in, to the extent you can. Please note: I don't have it all figured out yet. With your help, we can figure it out together, including the contribution process. Below are the things that currently need to be worked on. Documentation: Frontend documentation - for frontend developers: End-to-end how to work with ProcessWire Commerce in the frontend to build a shop. Backend documentation - for shop editors. How to use the GUI to configure, build, run and manage a shop. API documentation - for documenting how ProcessWire Commerce is built, developing for it and contributing. Still considering if/how to how to host documentation. Suggestions welcome. Fix Bugs Identify, report and suggest bug fixes. Please file bug reports in the repo here - https://github.com/kongondo/ProcessWireCommerce/issues. Fork the project, fix bugs and submit PRs. Tutorials Help write ProcessWire Commerce tutorials for different audiences. Help create demos. Ecosystem Help grow the project. Star it on GitHub. Create add-ons. Build migration tools. Create a logo for ProcessWire Commerce. Help write unit tests (???) Site Profiles Help develop an official, multi-lingual, modern site profile/theme to be used to showcase ProcessWire Commerce. Contribute site profiles or themes.
    1 point
  3. This week ProcessWire has an awesome new admin design thanks to the work of @diogo and @jploch of KONKAT Studio. You can get it now on ProcessWire’s dev branch! Read the latest blog post for details, screenshots, Q&A with the designers, and more: https://processwire.com/blog/posts/new-processwire-admin-redesign/
    1 point
  4. To me, representing an unset timestamp with a valid timestamp (i.e. 0) would seem misleading and lose information - even if an intentional 0 seems unlikely to occur! If for your purposes you want a 0 rather than an empty string, you can simply cast the returned value to an integer: $myDate = (int) $page->getUnformatted('my_date');
    1 point
  5. Padloper is dead! Long live Padloper! It is official! Padloper is now ProcessWire Commerce. ProcessWire Commerce is a free, open-source fully featured e-commerce module (plugin) for building and managing fully function online shops (stores) in ProcessWire. It is flexible, extensible, highly customisable, scalable, robust, multilingual by design and battle tested. Pro Support ProcessWire Commerce is designed to be easy to develop with and to use. For some, you might need extra reassurance that professional help will be available if you need it. Or, you might have a question about how to perform a certain thing or wish to support the project to ensure that any issues are dealt with quickly. Or you might want to sponsor a particular feature. If this is you, Pro Support and custom development can be purchased from my website. Community Support These forums. Donations If you value my work or my work helps support your work or you just want to say thanks, please consider donating. Thanks! Requests Modalities are still being worked out. Please note: I'll add features at my own pace; if and when I can (reasons for this discussed elsewhere in the forums). I'll focus on security, PRs and maintaining the project and major bug fixes. I hope community will contribute. Sponsored (pay for a feature) features: This can be by individuals or community driven. Please contact me for availability. Known Bugs ProcessWire Commerce Admin GUI is broken in the new admin theme, i.e., ProcessWire 3.0.248 (or newer). Save + Exit and similar broken on some pages at some recent ProcessWire version. Manually order creation broken (backend). Please file bug reports in the repo here - https://github.com/kongondo/ProcessWireCommerce/issues. Contributing This is a community project. All contributions are welcome! We are still working out how the 'how'. Documentation Please see this thread. Other Important Stuff Migrating from Padloper. Community help request. Tech Stack ProcessWire (PHP). Vanilla JS htmx Alpine JS Tailwind CSS MySQL Download Here you go!
    1 point
  6. Needed this today. This is what I used: <?php // on init of a module wire()->addHookAfter('ProcessPageEdit::buildForm', $this, 'moveStatusFieldAndHideSettings'); // the hook method protected function moveStatusFieldAndHideSettings(HookEvent $event): void { // do not change the UI for superusers if (wire()->user->isSuperuser()) return; /** @var ProcessPageEdit $process */ $process = $event->process; $p = $process->getPage(); // check for page template if (!$p->matches('template=basic-page')) return; // get status field /** @var InputfieldWrapper $form */ $form = $event->return; $statusField = $form->get('status'); // add field to content tab $tab = $form ->find("id=ProcessPageEditContent") ->first(); if (!$tab) return; $tab->add($statusField); // remove settings tab both from form and from UI $tab = $form ->find("id=ProcessPageEditSettings") ->first(); if (!$tab) return; $form->remove($tab); $process->removeTab('ProcessPageEditSettings'); }
    1 point
  7. Sounds like a bug to me and might be worth creating an issue on github? Other than that: Have you tried limiting allowed url segments via regex? Just tried with a regex that allows all url segments except ones starting with "test" and it worked: regex:^(?!test).*$ In home.php bd($input->urlSegment1); And the hook in init.php: $wire->addHookAfter("/test/{file}", function ($e) { bd($e->file); }); /foo/bar/ --> shows "foo" /test/foo.jpg --> shows "foo.jpg"
    1 point
  8. took me some time today to find out why my page was not showing up... i ended up creating a hook that does what apeisa had in his mind some years ago // set all languages active automatically $wire->addHookAfter('Pages::added', function($event) { $page = $event->arguments(0); foreach ($this->wire->languages as $lang) $page->set("status$lang", 1); $page->save(); }); does anybody see any danger in that? i'm not so experienced with multilang yet... edit: somehow it seems that ->setAndSave(...) does NOT work in this situation. @Can or @dragan can you confirm that?
    1 point
  9. @Macrura, your Micro Contexts idea is clever. The approach you are taking here (effectively a single template where fields may be shown/hidden and labels/descriptions changed depending on context) is in fact exactly what is done in Repeater Matrix. Every matrix item (page) actually has the same fields, but the field visibility and labels etc are controlled by the matrix type context. So that got me thinking that all that is needed to do something similar with Repeater Matrix is to add some control that allows the user to change the matrix type of an existing Repeater Matrix item. The advantages over the Micro Contexts approach are: You don't have multiple templates that must be kept in sync if new fields are added - if you add a new field to any given matrix type it is added to the single Repeater Matrix field template. You can do all your field overrides (visibility, width, label, description, notes) from a single screen (the Repeater Matrix field settings). So as a result it's quicker to set up and easier to maintain. I have put in a request to Ryan to add such a control, but I had a play around and managed to get something working with a couple of hooks. To use this... Create a new text field named 'block_type' (best to create a dedicated field for the purpose). Set the field visibility to 'Closed' (to keep it discreet). In your Repeater Matrix field settings, add the block_type field as the first field in each matrix type. Add the hooks below to /site/ready.php... // Change the block_type inputfield to a matrix type select $wire->addHookAfter('InputfieldText::render', function(HookEvent $event) { $inputfield = $event->object; $field = $inputfield->hasField; if(!$field || $field->name !== 'block_type') return; if($inputfield->name === 'block_type') return; // in case field is not being rendered inside repeater inputfield $rpage_id = str_replace('block_type_repeater', '', $inputfield->name); $rpage = $this->pages->get($rpage_id); if(!$rpage->id) return; // just in case $matrix_field_name = substr($rpage->template->name, 9); $matrix_field = $this->fields->get($matrix_field_name); $raw_matrix_types = $matrix_field->type->getMatrixTypes($matrix_field); $matrix_types = []; foreach($raw_matrix_types as $key => $value) { $label = $matrix_field->get("matrix{$value}_label"); $matrix_types[$value] = $label ?: $key; } $if = $this->modules->get('InputfieldSelect'); $if->name = $inputfield->name; $if->label = $inputfield->label; $if->required = true; foreach($matrix_types as $key => $value) { $if->addOption($key, $value); } $if->value = $rpage->repeater_matrix_type; $event->return = $if->render(); }); // Change the matrix type on saveReady $pages->addHookAfter('saveReady', function(HookEvent $event) { $page = $event->arguments(0); if(!$page instanceof RepeaterMatrixPage || $page->block_type === null) return; if($page->isChanged('block_type')) $page->setMatrixType($page->block_type); }); If you wanted to remove certain Repeater Matrix inputfield controls then you would use a hook/module as discussed in earlier posts in this thread.
    1 point
  10. Micro Contexts (aka field value contexts) Change any context-enabled setting in your page editor/template based on the value of a page reference field. Why use this? Say you have a template that is controlling some generic part of your website, like a section on the homepage, a widget, or an item in a media library. If you are using the various fields on this template in different ways depending on an option (page select) such as 'widget_type', 'media_type', etc, you can hot-switch the template context based on the field's value. Why not use template, like just change the template? Unfortunately, most of my clients would probably break down in tears if i tried to explain what a template is, or how to change it. This also allows you to have better more relevant labels, descriptions and notes based on any page ref field value on your template, as well as be able to show/hide fields based on that value, or even move fields around to make some more prominent or visible. How to use this 1.) Create a new template: 1a) Use the following name structure: mc-[field_name]-[field_value]-[any_memo_here] where [field_name] is the field that will control the micro context, and the [field_value] is the required value (page id) that the controller field must equal/have in order to trigger the virtual template context. The last part of the template name should be used for the page name, or some memo to make it easier to know from the templates list what field value will trigger the micro context, since the template name does require the ID value of the field, not the name. 1b) Make sure to specify the template you are contextualizing under "Duplicate fields used by another template" before clicking save! 1c) Edit your field settings for this template, for when your fieldname=value as specified in the template name (labels, descriptions, notes, visibility, field order etc.) 2.) Place this code in your ready.php file: wire()->addHookAfter('ProcessPageEdit::loadPage', null, function (HookEvent $e) { $page = $e->return; $mcPlates = $this->wire('templates')->find("name^=mc-"); if(!count($mcPlates)) return; foreach($mcPlates as $mcPlate) { $nameParts = explode('-', $mcPlate->name); // expected format: mc-[field_name]-[page-id]-[anything-you-want-here] $mc_field = $nameParts[1]; // the field controlling the micro context $mc_value = $nameParts[2]; // page id has to be the 3rd part of the template name $controllerField = $page->fields->get($mc_field); //if we find a matching controller field from the template name... if($controllerField) { $f_value = $page->get($controllerField->name); $proceed = false; if( ($f_value instanceof PageArray) || ($f_value instanceof Page) ) $proceed = true; // this only works with page reference fields. if(!$proceed) continue; // the page corresponding to the required value (page id) specified in the mc template name, to change micro context $mc_page = wire('pages')->get((int) $mc_value); // if the value specified in the mc template name matches the current value of the page reference field, change the // fieldgroup context $proceed = false; if( $f_value instanceof PageArray && $f_value->has($mc_page) ) $proceed = true; if( $f_value instanceof Page && $f_value == $mc_page ) $proceed = true; if($proceed) { $tName = $mcPlate->name; $mc_template = wire('templates')->find("name=$tName")->first(); if($mc_template) { $mc_fieldgroup = $mc_template->fieldgroup; $page->template->fieldgroup = $mc_fieldgroup; } } } } }); Caveats This probably needs more work to be fully usable, and may need more bullet proofing in terms of checking for valid template name, etc. You can only have this work with 1 page reference field per template. This has been tested and is being used on at least 2 live sites, but caution should be used, and the functionality should be tested before using on a live site. Screenshots: 1) a default widget with no field value context enabled fields 2.) A field value context enabled edit page for the 'Widget Type', the template controlling this is now 'mc-widget_type-1054-text', but the template of the page stays as 'widget'; only the fieldgroup context is changed when the page is loaded to get the contextual settings: 3.) the context for when the page reference field called 'widget_type' has the value of 1150, which is a video widget type (template name is 'mc-widget_type-1150-video'). Convenient Module edition coming soon!
    1 point
  11. Thanks arjen - you didn't take long to find it, it was only put together and released on Friday Glad you'll find it useful. Looking for some feedback for those who might start using this. I am thinking of adding an option to add an UnPublish button to the Content tab when the Settings tab is hidden. I have also discussed the issue here: https://github.com/ryancramerdesign/ProcessWire/issues/1048#issuecomment-87449770 Kinda wondering if Ryan would be willing to add a core solution, but if not, I might add it to this module, because that is the one thing that I think users may still need. Most other things on the Settings tab are just noise for the average user, but Unpublish can be important. What does everyone think?
    1 point
  12. In case you want it a little more simpler $pages->setOutputFormatting(false); $pag = $pages->find("template=basic-page"); foreach($pag as $p) { foreach($languages as $lang) { if($lang->isDefault()) continue; $p->set("status$lang", 1); $p->save(); } }
    1 point
×
×
  • Create New...