Jump to content

Leaderboard

Popular Content

Showing content with the highest reputation on 08/31/2024 in all areas

  1. This week we introduce a new module named Custom Fields. This module provides a way to rapidly build out ProcessWire fields that contain any number of subfields/properties within them. No matter how simple or complex your needs are, Custom Fields makes your job faster and easier. Not only does this post introduce Custom Fields, but also documents how to use them and includes numerous examples— https://processwire.com/blog/posts/custom-fields-module/
    5 points
  2. @ryan, thanks for creating this cool module! A couple of questions: 1. Do the subfields have an ID of some sort separate to the name, such that a subfield can be renamed without losing the existing data stored for the subfield? 2. What happens to stored data if a subfield is removed from the defining file? Does the existing data for the subfield persist in the database, or does the fieldtype detect the removal and do some cleanup to remove the stored data? Also, I think there's a typo in the blog post. // multi-selection foreach($page->custom_field->countries as $value) { $label = $page->field->label('countries', $value); echo "<li>$value: $label</li>"; // i.e. "USA: United States" } ...should be... // multi-selection foreach($page->custom_field->countries as $value) { $label = $page->custom_field->label('countries', $value); echo "<li>$value: $label</li>"; // i.e. "USA: United States" }
    5 points
  3. @bernhard thanks for the welcome and the comprehensive list of options! makes sense -- and I was not aware of WireHTTP before. I was able to change the module to use WireHTTP instead of Guzzle quite easily, so now no external dependency is needed. The changes have already been pushed to the github repo.
    4 points
  4. Version 2.2.15 is out! This update comes with a small performance upgrade. Now you can choose on which pages you want to embed the JS and CSS files of the FrontendForms module. This means that you can prevent the files from loading on pages that do not contain a form. This also allows these pages to load faster This version includes a new configuration field in the backend where you can select all the pages where you want the files to be embedded. Best regards
    3 points
  5. Hi @notplants welcome to the forum and thx for your contribution! There is no standard way of adding requirements. ProcessWire does not use composer or such. It is just a platform to run modules. How you add your dependencies basically is up to you. One option is to include it into your module. So you'd do composer require ... on your dev environment and then you add require vendor autoload to your module and that's it. That means it is super easy to install for anybody else, but that also means that if you (or anybody else) had multiple modules that require guzzle in the best case it would just be some overhead (as every module might ship a separate version of guzzle) and in the worst case you'd get conflicts. Another option would be to create another module solely for adding guzzle to PW. That way several other modules could use the guzzle module and you'd have less overhead, but more to do during installation or maybe also more troubles as you need to keep versions compatible... The third and in this case IMHO best option is to use WireHttp instead of guzzle unless you really need guzzle for the http requests?! WireHttp is part of the core so you get the best of option 1 and option 2.
    2 points
  6. I'm working on RockCalendar which will be released soon if everything goes smoothly 😎 I think it should be stable enough next month. If you want to get notified you can subscribe to the Rock Monthly Newsletter. The module uses https://fullcalendar.io/ for the calendar interface and when clicking an event it will open the page editor in a pw modal: Opening the modal was a bit of a challenge, because PW unfortunately does not offer a good JS API to open modals. It only offers markup-based options to control the behaviour of the modal - at least as far as I could find out. This is a problem, because all events in the calendar get loaded by fullcalendar and I only have the eventClick() callback where I need to fire my action. My solution is to create a fake element in the dom and trigger a click on that element: calendar.on("eventClick", (info) => { // create a fake link element in body let link = document.createElement("a"); let $link = $(link); $link.attr( "href", ProcessWire.config.urls.admin + "page/edit/?id=" + info.event.id ); $link.addClass("pw-modal"); $link.attr("data-autoclose", ""); $link.attr("data-buttons", "button.ui-button[type=submit]"); $link.on("click", pwModalOpenEvent); $(document).on("pw-modal-closed", this.refresh.bind(this)); $link.click(); $link.remove(); }); Maybe that helps anyone else looking for a solution to a similar problem. If anybody knows a better way how to do it, please let me know! PS: If you have input (feature requests) for the development of RockCalendar please let me know: https://processwire.com/talk/topic/30355-request-for-input-what-features-should-a-pw-calendar-module-have/
    1 point
  7. An example of how to use new discounts feature in Padloper 009 in the frontend. Important things to note: You can validate and apply discounts programmatically or by capturing details using your custom form. Padloper does not output a discount input since discounts are an optional feature. Padloper provides a discount API that allows you to validate, apply, invalidate, remove, etc. discounts from an order. You can submit your discount code form to the server however you wish, i.e. ajax or non-ajax. The example below applies a discount with code 'SAVE10'. This is a 10% whole order discount. The example uses htmx (ajax). The form is in the checkout page but the ajax endpoint can be a single place, e.g. your home page. Example Apply Discount Form Screenshots Discount form on checkout page Discount validation failed Discount applied successfully Example Apply Discount Ajax Form Handling Please see the comments in the code. Thanks.
    1 point
  8. Today while working on RockCalendar I had the need to change the database schema of my daterange fieldtime to add support for recurring events. I didn't know how to do it, so I had to do some research and that took quite some time. Here's the solution that I found in FieldtypeComments.module. When developing the fieldtype you can add a database schema like this and PW will take care of creating the table and columns for you: public function getDatabaseSchema(Field $field) { $schema = parent::getDatabaseSchema($field); $schema['data'] = 'timestamp NOT NULL'; // the from timestamp $schema['foo'] = 'timestamp NOT NULL'; return $schema; } This is quite easy, but I wanted to add another column and tried this: public function getDatabaseSchema(Field $field) { $schema = parent::getDatabaseSchema($field); $schema['data'] = 'timestamp NOT NULL'; // the from timestamp $schema['foo'] = 'timestamp NOT NULL'; $schema['bar'] = 'timestamp NOT NULL'; return $schema; } No luck. You will get an error that column "bar" does not exist. Ok, so we have to modify the table somehow... But we also have to make sure that this is only done once. How to we do that? The solution is to save the schema version to the field and use that to compare versions and conditionally update the schema: public function getDatabaseSchema(Field $field) { $schema = parent::getDatabaseSchema($field); $schema['data'] = 'timestamp NOT NULL'; // the from timestamp $schema['foo'] = 'timestamp NOT NULL'; $schema['bar'] = 'timestamp NOT NULL'; $schemaVersion = (int) $field->get('schemaVersion'); $updateSchema = true; $table = $field->getTable(); $database = wire()->database; if ($schemaVersion < 1 && $updateSchema) { try { if (!$database->columnExists($table, 'bar')) { $database->query("ALTER TABLE `$table` ADD bar " . $schema['bar']); } $field->set('schemaVersion', 1); $field->save(); } catch (\Throwable $th) { $this->error($th->getMessage()); $updateSchema = false; } } return $schema; } And maybe at a later point you want to add another column "baz": public function getDatabaseSchema(Field $field) { $schema = parent::getDatabaseSchema($field); $schema['data'] = 'timestamp NOT NULL'; // the from timestamp $schema['foo'] = 'timestamp NOT NULL'; $schema['bar'] = 'timestamp NOT NULL'; $schema['baz'] = 'timestamp NOT NULL'; $schemaVersion = (int) $field->get('schemaVersion'); $updateSchema = true; $table = $field->getTable(); $database = wire()->database; if ($schemaVersion < 1 && $updateSchema) { try { if (!$database->columnExists($table, 'bar')) { $database->query("ALTER TABLE `$table` ADD bar " . $schema['bar']); } $field->set('schemaVersion', 1); $field->save(); } catch (\Throwable $th) { $this->error($th->getMessage()); $updateSchema = false; } } if ($schemaVersion < 2 && $updateSchema) { try { if (!$database->columnExists($table, 'baz')) { $database->query("ALTER TABLE `$table` ADD baz " . $schema['baz']); } $field->set('schemaVersion', 2); $field->save(); } catch (\Throwable $th) { $this->error($th->getMessage()); $updateSchema = false; } } return $schema; } 😎
    1 point
  9. 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
  10. Wow Bernard! Your timing is incredible 😃. I'm looking into 'a calendar solution' for a specific use case. Not sure if this helps your development, but let me mention my requirements: This app needs to have an interface for a number of freelancers to update their availability for jobs - and be able to provide them an overview of job's they've been booked on. (that means a lot of user specific data) On the back-end these entries from freelancers need to be accesale for planners, who will create 'jobs' and assign them to freelancers if they accept them. Up until now i've been working with lists, but your view and interface sound very interesting to me. I've just subscribed to your newslette, eager to check it out when it's ready for sharing. My Big Thank You! in advance.
    1 point
  11. @Jim Bailie If I understand the question correctly, you want to convert several regular ProcessWire fields into a single Custom Field? There isn't an automated way to do that. I suppose there could be though, as they are using all the same configuration properties.
    1 point
  12. Oh excellent, thanks! I’ve been asking myself this, but been too lazy to actually figure it out instead of just changing the table manually for project-specific modules 😄
    1 point
  13. I can give a quick reply about the Geffen calendar, but most of what there is to know about it is in that article I wrote. How the show performances (events) came to exist wasn't a concern as that was managed with a 3rd party service, obtained via an API and stored as child pages of a show. The main takeaway from that project was that we needed to simply display upcoming shows in a monthly calendar format (large and small) and when I originally developed the site, I leaned on FullCalendar. However that was total overkill and difficult to maintain because FullCalendar is more than just a way to display events in a calendar format, but an interactive component with dragging and dropping like what you'd get in a real calendaring system (Google Calendar, etc.). It's also built with complex JS which I like to avoid. I just needed an easy way to display information with simple AJAX loading between months. To solve those, CSS Grid (ie, "display:grid") and HTMX fit perfectly with some straight-forward PHP code to build it. One extra improvement that can be made to display a large and small calendar in different contexts while using the same HTML is to use container queries, but because browser support for it a couple years ago was still very low, I avoided it.
    1 point
  14. Version 2.2.14 is out! This new version comes with a new CAPTCHA type: a slider captcha. Now FrontendForms supports 7(!) different CAPTCHA types and I guess this will be the last one. There is a fabulous module in the module directory which also creates a slider captcha that can be used with other forms: Slide Captcha. But the slider Captcha in FrontendForms is an extra coded and integrated captcha, that has nothing to do with this module. To be clear: The slider captcha inside FrontendForms is similiar to the Slide Captcha module, but it has nothing to do with it. So there is no need to install the other module. The only thing you have to do is to enable the slider captcha in the module configuration - that is all. You have 1 additional configuration field where you can select the accuracy of the puzzle piece to the goal. 5 means that the distance of the puzzle pieces to the target must be less than or equal to 5px in order to solve the captcha correctly. Here you can see the new slider captcha in action: As always, please report any bugs on Github!
    1 point
  15. I became so used to use Template Field Widths that I almost always install it on larger projects. Super fast editing of values, tabbing around and done.
    1 point
×
×
  • Create New...