Leaderboard
Popular Content
Showing content with the highest reputation on 05/15/2023 in all areas
-
I did my first talk ever yesterday @ PHP Meetup Vienna!! Once more everything was a lot more work than I first thought, but I'm quite proud of the result ? What do you think? Did I forget something important? It was really hard to put 10 years into one hour... The recording was not planned at first, but I thought I'd just give it a try and everything worked quite well ? If you like what you see please share it with others so that ProcessWire gets the attention that it deserves ? Special thanks to @gebeer for showing me ProcessWire in 2013 ?3 points
-
Quick thought - could you check your server has a time sync service enabled (ntpd, chronyd or systemd) and that the time is accurate on the server. Perhaps you could update the ProcessLogin.js code to console.log(startTime) as well, and post the results here? Maybe compare it with console.log(new Date().getTime()) from your browser console. Then we can get a feel for how far out of step the server and browser times might be?3 points
-
Based on my recent post and your answers in Module: ProcessWire Core Upgrade I decided to no longer hijack that thread and therefore open this one. @bernhard asked some very good questions there and here are some of my answers. First and foremost, I keep all of my "Automation Hooks" at /site/ready.php, and they are not present in all of my projects. I mostly utilize them in larger long-term projects and projects in which I have devoted a significant amount of effort - see samples below. I considered building a module for each project so that I could keep it around, fork it, alter it... that kind of dev approach. But that didn't work out as expected, so everything was moved back to ready.php - which actually works best for me. One file in plain sight, right next to everything else. For these activities, I have my own collection of snippets. I simply grab the appropriate snippet, tweak it, position it, test it, and proceed from there. No overly complicated workflow at all. But why should I care if there are any module changes (see thread above) if I'm not going to update them right away? I'm curious about what's going on in each project. I can see which modules were installed, which are in use, and which may be upgraded the next time there is a release. I rarely update modules or anything else outside of my development environment. I learned my lessons here. This isn't something I'd use in a project in which 99% of the code consists of echo/foreach like in some smaller sites I built. I honestly don't care because their code base and modules will almost certainly never be touched again. Projects like these are a totally different thing - some of those "Automation Hooks" are in place there: What things I "automate" and have in place across my projects - to give you an idea why this makes my life easier. Checking for news updates (weekly) No updates in the last 2 weeks? Remind the client to say something on their website and suggest doing so on social media, Google Business, and everywhere else too. Checking event count (weekly) Only 3 events left? Tell the client to check this and update the event pages or at least post something in the news to tell visitors what's going on. Checking newsletters (weekly) No newsletter in the last 2 weeks? You get the deal: the client will be notified to either send a newsletter or hand out content so someone else can do this Checking lunch deals (daily) Same as above. A restaurant runs out of lunch deals and will be notified via email right away. Archive old stuff (weekly) Short term content, like lunch deals, don't have to stay in there until the end of days. Archive them under another branch of pages, delete/trash them. Out of sight, out of mind. Checking for TODOs (weekly) This is a special one as I sometimes like to add a notes field to content pages in which I can write down things I need to do on that specific page in a project. I look for all pages having content in this field, put everything in a mail and go from there. It's something like a TODO app but direct in the project. No Jira, Asana, Todoist needed for this. There are plenty other options available. In my situation, it varies depending on the specialty, the project's budget for maintenance, or the overall scope of my tasks. I typically utilize these "Automation Hooks" to learn more about a project and remain informed. Sometimes it's for the client, but it's all automated. There have been projects performing comparable automated tasks for over a year now or more, and the customer is thrilled to receive an email every now and then with a list of things he should do. WINNER WINNER! I get paid to remind him, and he gets things done. You could put anything you wanted in those. File counts, database size, login errors, PHP version, PW version, and so on. Ping at @flydev @monollonom @horst3 points
-
A friend of mine has changed his job, he owns a video game room, he now "develops" websites, I could see a result, and the tools used, I prefer to keep quiet here (it's in the title). I have to interfere in his conversion process before it's too late: Have the right habits, keep in mind that the goal is to help the client to improve the conversion of his business through his website, and thus to make more money rather than losing it. Otherwise, what's the point, an instagram or facebook page would have been enough. So I wanted to make a synthesis of the arguments to make him take into account, I also saw an old forum thread that came up recently, so I wanted to ask a neutral "person" (person.. lol) what she think. I have the impression that the arguments are those already exposed in the answers given to these threads. In short, a good synthesis, I think, and non-biased, I hope. As always, the same question, "How to convince my client to use Processwire instead Wordpress?" Yours sincerely, GPT ?1 point
-
After a previous request for Webp support (6 years ago, times flies…) that Horst and Ryan kindly introduced in PW 3.0.132, I'm back with another request for a new image file format, AVIF, which has landed in almost all browsers. I'm actually surprised no one here in the PW community has been asking for AVIF support in ProcessWire as it seems to be provide much more consistent gains in compression and greater relative quality over Webp, and of course over good old JPEG. My experience using it definitely confirms this. I've been using Cloudinary to serve AVIF images to the browsers that support it, but of course I'd rather not use a third-party service, and use it natively in ProcessWire. Imagemagick supports AVIF if I'm not mistaken. Anyone else is interested?1 point
-
Following up from the module mentioned last week, the PageEditRestore module has been released and here's a new blog post with all the details. This module helps to prevent page edits in the admin from getting lost when the user’s session is lost— https://processwire.com/blog/posts/page-edit-restore-module/1 point
-
This week ProcessWire 3.0.217 is released with 10 issue fixes, 2 PRs and a couple of minor additions too. See the dev branch changelog for details. Recently a client called me in a panic because they'd spent a few hours making edits to a page, and when they finally hit save, they were no longer logged in, so their changes were seemingly lost. I guess that their IP had changed somehow, or they kept the page editor open overnight or something. Whatever it was, they were now sitting at the login screen with their changes apparently lost forever. Luckily this person left that window as-is and contacted me to see if there was any way I could recover their changes. I quickly edited their /site/config.php file and temporarily added these: $config->protectCSRF = false; $config->sessionFingerprint = false; Next, I asked them to open another tab and login there. Once logged in, they returned to the tab where the page save failed, then hit "reload" in their browser, and their changes were saved. Phew. Thankfully that worked, but if it didn't, the next thing we were going to try was to open the browser inspector "Network" tab, and then copy/paste the edited content right out of the browser's POST data and into the CKEditor HTML source window. I imagine this has happened to others and perhaps they weren't so lucky as to recover the unsaved changes. So how can you avoid this issue? The best bet is to just save your work regularly. But that doesn't always happen, no matter how many times we communicate that to the client. So you can reduce the probability of it by making a couple adjustments to your config.php file. One change would be increasing your $config->sessionExpireSeconds. But the default is already 86400 seconds (1 day), and I'm not sure many really take more than a day between starting an edit and saving it... though I'm sure it happens. Another change would be turning off the $config->sessionFingerprint (or loosening it, see fingerprint settings). That's trading security for convenience, which isn't ideal, but it would prevent a changed IP address from expiring the session. Another thing you can do is install the ProDevTools UserActivity module, which keeps a ping going to the server, preventing you from getting logged out due to inactivity. Though this doesn't prevent a changed session fingerprint from logging you out, though it at least alerts you as soon as you've been logged out. Even the above changes might not completely solve this issue, and I don't like to tailor session settings around this case either (reducing security), so I've been thinking of alternatives. After dwelling on it for awhile, I started working on a module that saves non-authenticated POST requests sent to the page editor... saving data that would otherwise get lost. Then when you go back to edit the page, it alerts you that there are unsaved changes and asks you if you want to save them. When you answer yes and hit "save", it repopulates the unsaved POST data back into $input->post before the page editor has had a chance to process it. There are of course some security considerations here, so it has to be built carefully. I should also mention that it won't help much if it's the client's computer or browser that has frozen (there's the PageAutoSave module that can help with that). Though data loss due to a frozen computer/browser is likely even more rare than session loss. I don't have this module fully working just yet (it's a work in progress), but it's relatively simple so it probably won't take long. It's not going to catch everything; it won't save files, for instance. But it will catch the most likely cases, such as changes to those big "body copy" fields that someone might spend hours making edits with. I'll post more about it when I've got it a little further along, if there's interest. Thanks for reading and have a great weekend!1 point
-
This sort of thing sometimes happen to me when Tracy Debugger is on, and I get an unexpected warning from some random module that messes up any ajax response by errors appended or prepended to it. Maybe you could take a look in the Network tab to see what you got in the pagination response?1 point
-
Hello @Andy Thanks for your input on date fields. To be honest, I have not focused on date fields, because I did not use them a lot, but you have inspired me to enhance them. At the moment, only these 4 date validations can be performed: date - Field is a valid date dateFormat - Field is a valid date in the given format dateBefore - Field is a valid date and is before the given date dateAfter - Field is a valid date and is after the given date You will find examples of these validations at https://github.com/juergenweb/FrontendForms/blob/main/Examples/field-validation.php#L210 I will take a look of what can be implemented of your suggestions. To sum it up once more.: You will need to set a time range on a date field, where dates in between are allowed, others are forbidden You will need a validator, that checks if the date entered in a second date field, is inside a specific time range depending on the date entered inside the first field To the first point, I guess I can write a new method, so you will be able to set the range ( fe $field->setRange('15-05-23', '15-06-23')) or something like this, where first parameter ist the start and the second parameter, the end point of the time range. To the first point: you can set a time range with dateBefore and dateAfter validators: $inputDate = new \FrontendForms\InputDate('date'); $inputDate->setLabel('Input Date'); // add the time range between 01-05-2023 and 30-06-2023 $inputDate->setRule('dateAfter','2023-04-30'); $inputDate->setRule('dateBefore', '2023-07-01'); $form->add($inputDate); For the second issue I guess I have to write a new custom validator, which takes care of the date in the first field. I will take a look what I can do :-)1 point
-
Hi @Juergen Thanks for this module. I can see that a great and good job has been sold. The main problem why I still use custom forms is the date picker. The first problem is to set the range of acceptable times to specify. The second is to inform the user of a date error if the range is still not respected. You do realize that both POST and GET are not perfect. The other case is when the user needs to specify a range of a start date and an end date. There are more error options here. There is also a variant when dates are linked. For example, after specifying the first date, the second date can be as much as two weeks later. Usually such collisions are solved with jQuery. I looked at your module documentation and didn't see any examples with dates. Maybe you have a similar functionality, but I would like to see an example.1 point
-
Brilliant talk Bernhard - I picked it up through the PW Weekly over the weekend. You're a great spokesperson for PW on the whole and of course very talented - I use your modules like RockAwesome and RockMailLogger on just about every PW instance. Now I need to learn more about Latte!1 point
-
1 point
-
@szabesz The roles/users/templates part would be possible. But for someone that has access to the page editor, is there any reason not to give them access to save/restore something that they lost? The tool doesn't give them the ability to restore any fields beyond what they already have access to. I guess I see it as something that ideally wouldn't be limited by access control since it's a tool to prevent lost work, rather than a tool providing any kind of enhanced access. Though maybe there are use cases I haven't considered yet. As for deciding what fields should be restorable, that part is a little more tricky because it doesn't actually have any idea what fields it's saving or restoring. It's not actually saving or restoring fields. Instead, it's saving and restoring the raw POST data from the request. It would be easy to identify a TinyMCE field named "body" in the POST, but it would be quite a bit more difficult to identify the the same field within a repeater or other more complex type. If it offered the ability to select which fields it can save/restore, then it would have to know the POST data naming conventions used by all of the fields and subfields within them. This is where it would get significantly more complicated to configure and maintain, and more prone to bugs. Whereas now it just simply restores your lost POST request, providing the same result as if your "Save" had worked, rather than failing due to session loss. It doesn't have to know what all the variables in the POST request are for, so by just saving/restoring it all, there's very little chance for the module to screw up anything.1 point
-
1st thought: Wow, that is brilliant!!! 2nd thought: We have to build a module from/for that!! 3rd thought: Hm... How would I actually use it. What fields would we need to have? Would I actually want to update, just because there are updates? Isn't it actually more dangerous to update modules than to just leave them untouched? I mean - I'm also keeping all modules up to date usually, but in general that happens during development so I'm hands on that project and I instantly see if something breaks. So how are you thinking to use that @wbmnfktr and others? I'm also happy to read about RockMigrations, though I wonder if the use case would be a good one for RM... It's actually built more for the opposite of reverting changes. It's really good add adding/changing things, but I'm usually reverting things just by git reset and/or "php rockshell db-restore" I really like the idea of having some kind of PW Assistant (or copilot) that notifies the admin about important things. It would be to define thought what those important things could be. I could think of several things like monitoring file count, file size, db site, file permissions etc. of an installation. Maybe also a 404 monitor or such. Maybe I'm already too many steps ahead, but I think if I really wanted to add something like this it would need to be something really useful and just updating for the sake of being up to date is just not enough for me ? Edit: Related: https://processwire.com/talk/topic/28499-automation-hooks-make-life-easier/#comment-2327651 point
-
Uploads: Three way (all upload to the current category): DnD Via right click which pops open a contextual dialog and you select 'upload' Via the 'New' button, which pops open a contextual dialog and you select 'upload' New Button: Opens a dialog/dropdown from which you can choose : 'new folder', 'file upload' or 'folder upload' [this latter one will also create the virtual folder, i.e. category] By default, yes, it is the entire library. However, there will be advanced search, accessible by clicking some icon within the search box. It will open a dialog within which you can set search parameters such as type, name, date, category, etc.1 point
-
Like ProcessWire page reference fields. Yes. Media pages are not nested. They reference 'categories' (folders) which themselves can be nested. To the user, they look like 'folders' in everyday computing (sort of). Conceptually, they are virtual folders. Technically, they are like page reference fields. This means that a media item can belong to more than one category. This is achieved simply by it referencing multiple 'category pages' (like page reference fields). So, technically, we don't nest media items. Instead, we nest the categories and the media items follow that, virtually. Categories are nestable pages. For instance, in the demo, People is a top level category (folder) page. It has two (ProcessWire) page children, Men and Women. If we wanted to, we could further sub-divide this, e.g. Men > Sports Men > Martial Arts > Etc... These are all 'category' pages. It is not shown in the video but from the screenshot below, you can see the category 'Fruits' is deeply nested. Deep Nesting Back to the demo, for example, the images (media items) you see when viewing 'Men' have the category 'Men'. Definitely. This is because as explained above, we don't nest the media items themselves. Their paths are fixed. For instance, to move some media from the category 'Berries' into 'Apples', behind the scenes, we will just change its category (reference) to 'Apples' (or 'Green', to be more specific). The media itself doesn't move. I am still working on the 'move' from the UX point of view but it will most likely be via both drag and drop and using menu (context) options.1 point
-
Version 1.2.3 is ready! PLEASE DEINSTALL THE OLD VERSION OF FRONTENDLOGINEGISTER AND UPGRADE FRONTENDFORMS TO THE LATEST VERSION BEFORE, BECAUSE THERE ARE A LOT OF CHANGES AND NEW FEATURES!! OTHERWISE YOU WILL GET ERRORS! Beside fixing a lot of bugs, this new version supports upload for an user image too. Supported Fieldtypes for images are FieldtypeImage and FieldtypeCroppableImage3. Please note: You can only use ProcessWire image fields with single upload - multi-upload fields will be ignored and cannot be selected. So if you want to use an existing image field or you need to create a new one, take care to set the image upload only to 1 single file. After you have added this field to the user template, you can select this field inside the module configuration and add it to the profile form and/or to the registration form. Take also care that this field is editable by the user, otherwise it will also not be selectable. Just to mention: Technically you can add as many image fields as you want to these 2 forms, but it would not make sense, because each user needs only one image. But if you want.... you can. There were a lot of changements taken, so please let me know if you discover issues. Best regards1 point
-
This is because Page Autocomplete doesn't use InputfieldPage::getSelectablePages. Instead, it sends a live query to ProcessPageSearch. Unfortunately, this means that the field settings are written to the JS config, and support for selectors is somewhat limited there. There's been a github issue around for some time with a workaround, which unfortunately means adding a few lines to a core js file, so it needs to be reapplied after every update: https://github.com/processwire/processwire-issues/issues/1374#issuecomment-8350329781 point
-
I had to give it another spin/try. Reasons to convince a developer or web design agency: Reasons to convince a client:1 point
-
Ok, Claus! You are close to the solution.? You will get every value by its name attribute. To add all of them to the body, I recommend you concatenate all the values in one string. $email = $form->getValue('email'); $message = $form->getValue('message'); If you have all of your $_POST values than you create your body string (fe with a little HTML markup). $body = '<ul><li>Email: '.$email.'</li><li>Message: '.$message.'</li></ul>; As the last step, add it to the mail body: $m->body($body); // or if you want to use HTML markup $m->bodyHTML($body); You will find a working example at https://github.com/juergenweb/FrontendForms/blob/main/Examples/contactform.php Best regards PS: If you will need help, please post the code of your form here.1 point
-
Hello @xweb The placeholder is an attribute and you can add every attribute with the setAttribute() method described here. $yourField->setAttribute('placeholder', 'Enter your first name'); // or with translatable strings $yourField->setAttribute('placeholder', _('Enter your first name')); Replace $yourField with the variable name of your field object and your done ?! You can do this in the same way for every attribute (class, data-attribute, id, rel,.....). Have a nice day! Jürgen1 point
-
Version 2.1.19 contains changes to make the module compatible with PHP 8.2 and following versions. All dynamically created properties have been removed and replaced by a declared property which hold all the properties inside an array. The reason for this is that dynamicalle created properties will be depreciated in 8.2 (leads to a warning) and the will be forbidden in upcoming PHP 9. So, this was a change affecting a huge amount of files. So please test it carefully and report any issues directly on GitHub. IMPORTANT! Due to a writing mistake, there are wrong values inside the database: These wrong values will not be overwritten during the update. It is recommended to uninstall and reinstall the module after the update to be sure that the correct values are stored inside the database. Otherwise it is most likely that you will get an error after a form submission. Just to mention: the error is in the fieldname of the custom messages: instead of the field name "input_alertErrorText" and "input_alertSuccessText" I have written "input_input_alertSuccessText" and "input_input_alertErrorText". This causes an error after form submission. Thanks a lot!1 point
-
Would be nice to update the Fontawesome icons in PW core, so they can be used for labels in the backend. The current version 4 is quite old and has a very limit set of icons. Version 6 also has a free version with more icons. The implementation seems to be very similar, so it should be easy to implement. The icons can be downloaded here.1 point
-
1 point
-
Could you please download and replace the following file: https://github.com/juergenweb/FrontendForms/blob/main/FrontendForms.module Let me know, if the error is gone1 point
-
Ok, give me a minute, I will add an if condition. In the meantime you can take a look at the example of uploading a file to page. https://github.com/juergenweb/FrontendForms/blob/main/Examples/fileuploadtopage.php This is the way to go - I have tried it and it works in my case.1 point
-
From the recent discussion about the roadmap & wishlist for 2021 and some other posts by @ryan, it comes to my mind that developing and coordinating the whole project for one person is becoming harder and harder and leads nearly to the reverse of expanding the ProcessWire ecoysystem. This is not against Ryan, i think everyone here knows how engaged he is about ProcessWire, but he has only 24/7 (sometimes i think he's got far more than that...). We as the community could support the project (financially) to relieve Ryan and could take over some tasks from him. This could be, but is not limited, to: Building a Foundation/Association/Company to ensure the persistence of the project and to fund the work put in ProcessWire of Ryan (and others). Nearly every other CMSs i checked has something like this (Drupal Association, Typo3 Association, Joomla Foundation, Wordpress Foundation, Contao Association, ...). This also puts more trust in the project, if someone new will check on his engagement in ProcessWire. Assigning persons/teams to work on things: Extending the core (when necessary) Developing and maintaining major modules (e.g. page builder, admin themes, internationalization, marketing, ecommerce system, ...) Testing and inspection of modules developed by others Making translations of modules (translation of the core is mostly covered, i think) Working on PRs & issues submitted on github Working on the homepage Coordinating the community efforts I know, some resorts are already covered by others (e.g. @Pete for the forum, @horst for images, ... ), but there are many other areas where this ist not the case. By joined efforts by the ProcessWire community this hopefully will also attract new developers to the system and by a growing number of users this assists in the things above in a circular process. What do you think?1 point
-
Building your very own custom Fieldtypes in ProcessWire seems to be hard, but it actually is not, once you get the concept. In this post I'll share a simple and as minimalistic module as it can get that everybody can use as a boilerplate for his own Fieldtypes. A Fieldtype that does not store any information in the database A Fieldtype that stores information in the database (to be done) Make your Fieldtype configurable 1. A Fieldtype that does not store any information in the database Some of you might know the excellent RuntimeMarkup module by @kongondo. I've used it a lot in the past, but I get more and more into developing custom fieldtypes rather than hacking the runtime module to my needs. That has several advantages, but it has also one major drawback: It is always a pain to setup a new Fieldtype, because there are lots of methods (see the base class /wire/core/Fieldtype.php) and you have to know which methods you need, which ones you have to remove and adopt etc.; Not any more! Ryan has developed a showcase module (the Events Fieldtype) to learn from, but when I first peaked into it, it felt quite complex and I thought it would be a lot of effort to learn Fieldtype development). There are also some easy and small Fieldtypes to learn from, like the FieldtypeCheckbox. But all of them require a good understanding of what is going on, you need to modify existing config inputfields that might have been added to that fieldtype and afterall it's not as easy as it could be. With my new approach I plan to use a boilerplate fieldtype to start from (in OOP terms to "extend" from) and only change the parts i need... More on that later. Here is the boilerplate module with some debugging info to illustrate the internal flow on the tracy console: See the module in action in the tracy console ( @adrian has done such an amazing job with that module!!!): The code should be self-explaining. What is interesting, though, is that after the ### getUnformatted ### dump there is only one call to "___formatValue". All the other calls (loadPageField, wakeupValue and sanitizeValue) are not executed because the value is already stored in memory. Only the formatting part was not done at that point. With that concept it is very easy to create your very own custom Fieldtypes: <?php namespace ProcessWire; /** * Demo Fieldtype Extending the Boilerplate Runtime Fieldtype * * @author Bernhard Baumrock, 03.10.2018 * @license Licensed under MIT * @link https://www.baumrock.com */ class FieldtypeDemo extends FieldtypeMarkup { public static function getModuleInfo() { return [ 'title' => 'Demo', 'version' => '0.0.1', 'summary' => 'Demo Fieldtype', 'icon' => 'code', ]; } /** * convert the wakeupValue to the given format * eg: convert a page object to a string */ public function ___formatValue(Page $page, Field $field, $value) { $value = parent::___formatValue($page, $field, $value) . " - but even better!"; d($value, '___formatValue --> convert to whatever format you need'); return $value; } } Notice the change "but even better" in the last two dumps. I think it can't get any easier, can it?! ? I'll continue testing and improving this module, so any comments are welcome! 2. A Fieldtype that stores information in the database See this module for an easy example of how to extend FieldtypeText:1 point
-
Memo to myself and mybe to safe someone else from losing hours trying to understand why a multi-language Inputfield does not render() as expected... Learnings: 1) Inputfield::render() is only hookable for single-language Inputfields! When PW renders a multi-language Inputfield the LanguageSupport module adds a hook that fires after the original Inputfield::render(). This hook calls the render() method for each language and to avoid circular references it does that directly on $inputfield->___render() and not $inputfield->render(): https://github.com/processwire/processwire/blob/51629cdd5f381d3881133baf83e1bd2d9306f867/wire/modules/LanguageSupport/LanguageSupport.module#L445-L453 2) When building a custom Inputfield that supports a multi-language setup it is critical that its render() method is defined with 3 underscores! Otherwise the LanguageSupport hook that adds the markup for the other languages' fields would not fire.1 point
-
Both the list on the Modules page and the fieldtype select on field edit screen expect fieldtype module names to start with "Fieldtype". BaseFieldtypeRuntime starts with "Base", so it's grouped under "Base" on the Modules page, and also not included in the fieldtypes (wire)array managed by the core (see /wire/core/Fieldtypes.php).1 point