Leaderboard
Popular Content
Showing content with the highest reputation on 06/02/2023 in all areas
-
ProcessWire 3.0.219 on the dev branch focuses primarily on a major overhaul to the core $modules system. The Modules class had grown into more than 5000 lines of code — all related to modules, but with lots of different areas of focus within that. It had become a little bit messy, fragile and hard to maintain at that size. I've had @todo notes in the class to "clean it up" for quite awhile, but this week I finally got to it. The approach is similar to that of our $pages API (Pages class), which is split into separate classes for page finding, loading, editing, caching, etc. The Modules class has been split into several much more focused classes for module information, installers, loaders, files, flags, duplicates, and configurations. This leaves the main Modules class as the gatekeeper, making it less fragile and easier to maintain. If this overhaul was perfect, you shouldn't notice any difference, and the public $modules API remains as before. But with such significant overhaul that took a full week to complete, there's also an increased potential for temporary errors, so please let me know if you encounter any. Thanks for reading and have a great weekend!14 points
-
Just to let you know. Todays demo was a full success. Online booking project will enter next testing stage. However it‘s not yet decided if the project will be realized with PHP/MySQL and Processwire, or Python/Django as the companies internal CMF/CMS of choice used for about 80% of all internal projects.3 points
-
If I'm reading this correctly, the confusion is all about what "age of cache" means, right? Currently "age of cache" refers to the expiration time of the cache, not to the time it was stored. Meanwhile you expected it to mean the time the cache was stored. I've always assumed age to refer to the expiration time, but you are correct — it is not unreasonable at all to expect age to refer to the time of storage ? In terms of documentation, something along the lines of "Optionally specify expiration time" and "If cache exists but has expired, then blank is returned" would perhaps be more in line with actual behaviour, but generally speaking the rule of thumb is that in this context "age" is about "expiration time" rather than "storage time". To be clear I'm quite certain that the way the function works and the way it calculates expiration is exactly how it was meant to work — and even if it wasn't, changing it at this point would be a major breaking change in terms of behaviour for existing setups.3 points
-
I've just released RockFrontend 3.0 https://github.com/baumrock/RockFrontend/releases/tag/v3.0.0 @netcarver found that .less and .latte files were publicly accessible if you knew the file path (eg example.com/site/templates/sections/footer.latte) which is for sure something that you don't want even though it should not really be a security concern. Sorry for that and thx for spotting @netcarver ! The latest release updates /site/templates/.htaccess to block access to .latte/.twig/.blade/.less files so be sure to upgrade RockFrontend in all your installations! Other than that I've also changed the way how RockFrontend loads assets and I'm not 100% sure if that might introduce issues in existing sites, so be sure to check if everything works as expected. New features: RockFrontend now ships with https://github.com/wasinger/htmlpagedom wich let's you parse and manipulate html markup which can be super handy in several situations. I'm using it on my new website where I'll show docs for all my modules that are rendered from markdown files and add some magic here and there via manipulating the resulting html that comes from the markdown parser. Improvements for the Topbar: There is now a toggle that makes it possible to hide/unhide the bar instantly (and persistantly). Also you can add your own custom markup to the topbar by adding custom markup to $rockfrontend->topbarPrependMarkup or topbarAppendMarkup.2 points
-
For testing reasons, I added the following code after this line to make sure get() is never called in two-argument form. if($func === null) throw new WireExeption('Illegal use of $expiry argument in WireCache::get without a function argument'); So far, I haven't seen any exceptions, even when running maintenance. I'm going to run a lot of tests anyway over the next week as I'm in the process of finalizing my Redis WireCache module. Unless something unexpected pops up there, the docs should probably be amended to read: /** ... * @param int|string|null|false $expire Optionally specify max lifetime (in seconds) OR expiration time as a date string, or false to ignore. * - Do not pass in $expire when calling get() without a $func argument, since the results are likely not what you expect * - If using a $func, the behavior of $expire is the same as that of save(). ... */2 points
-
Hi all, I've released 0.9.0, which brings the minimum PHP version to 7.4, adds support for PHP 8, and adds support for Composer 2. Also released 0.9.1 which handles @gebeer's suggestion (thanks!). Note, however, that I've published these versions on a hunch that they will be ok – I do not have a PW setup for testing. If something is broken, let me know and I'll fix it.2 points
-
I did it … #1743 - update: this is fixed in processwire 3.0.220, I can confirm that this is working now as expected.2 points
-
I'm really in love with FormBuilder, but the one thing missing to match all my end users' expectations were repeatable field groups. Think repeaters, in ProcessWire terms. Our primary application of PW is our corporate intranet, so "lines" of fields are quite common in the forms I build. We have all kinds of request forms where the information for a varying number of colleagues needs to be entered (from meal order to flight booking request) and where it is simply impractical to send a form for each, and I don't want to clutter my forms with multiple instances of fields that may only get used ten percent of the time. That's why I started to build FormBuilderMultiplier (link to GitHub). What it does: Adds an option to make a regular Fieldgroup repeatable Lets you limit the number of instances of a Fieldgroup on the form Adds an "Add row" button the form that adds another instance of the Fieldgroup's fields Adds a counter suffix at the end of every affected field's label Stores the entered values just like regular fields Makes the entered values available in preview and email notifications Supports most text based fields, textareas and selects (really, I haven't had enough time to test all the available choices yet) What it doesn't do (yet): Support saving to ProcessWire pages (i.e. real Repeaters) I haven't tested all the validation stuff, Date/Time inputs etc. yet, but since I'm utterly swamped with other stuff at work, I didn't want to wait until I have it polished. Any feedback is welcome. There might also be some issues with different output frameworks that I haven't encountered yet. The forms I work with mostly use UIKit. Status: Still alpha, so test well before using it in the field. Known issues: When rows are added, the form's iframe needs to be resized, which isn't completely clean yet. How it works: The Fieldgroup settings are added through regular hooks, as is the logic that adds the necessary field copies for processing the form and displaying previews. "Multiplied" field instances are suffixed with _NUM, where NUM is an incremental integer starting from 1. So if you have add two fields named "surname" and "givenname" to a fieldgroup and check the "multiply" checkbox, the form will initially have "surname_1" and "givenname_1" field (I'm still considering changing that to make the risk to shoot oneself into the foot by having a regular "surname_1" field somewhere else in the form less likely). When a "row" is added, the first row is cloned through JS and the counter in the fields' IDs, names and "for" attributes as well as the counter in the label are incremented before appending the copies to the Fieldset container in the form. To keep backend and frontend in sync, a hidden field named [name of the fieldset]__multiplier_rows is added to the form. Both the backend and the frontend script use this to store and retrieve the number of "rows". ToDo: Naturally, add the option to store the data in real repeaters when saving to pages. Do a lot of testing (and likely fixing). Make a few things (like the "Add row" button label etc.) configurable in field(set) context. Add a smooth API to retrieve the multiplied values as WireArrays. The mandatory moving screenshot:1 point
-
date - Documentation - Twig - The flexible, fast, and secure PHP template engine Says here you can change Twig’s default date format like this: $twig = new \Twig\Environment($loader); $twig->getExtension(\Twig\Extension\CoreExtension::class)->setDateFormat('d/m/Y', '%d giorni'); And format individual expressions like this: {{ page.created|date("d/m/Y") }} But to get Italian words like ”giugno“ or “venerdi” you’ll probably need something called “Twig Intl Extension”: https://stackoverflow.com/a/755727041 point
-
Actually the cached files are cleared if they are expired but only through a LazyCron: (from the ProCache’s page) In other words, if you still have apache running and your database is down, you should not have to worry, so long as your website is fully cached.1 point
-
Do it now! It is easy to setup, and once you have it, you will never want to touch something other again.1 point
-
Thanks both. I think the confusion arises because age is used to mean 2 different things in the cache context. In code, it's $expires in both contexts. For save() and also for get() when a function is also provided $expires means when the data should expire. For get() when a function is NOT provided $expires means "get if the thing expires before this new $expires, oh but also if it never expires (because of that 2010 date that's used to mean never expire...)". The 2nd case is my beef! Typically, when wanting a cached value, you care to fetch it unless it's too old for you to rely on. I can see the use case that you cache something with a long expiry, but that one user might only want to use a value if it's not that old. But that's not what we have. We have sort of the opposite: get something if it's going to expire before the given date. I'd love it if someone could give a scenario in which this was useful. Perhaps the use-case is cache warming? Like you might want to get stuff that's going to expire soon, and update the cache now. We could then use get($name, $expiry) and then recalculate the value and save() with a new expiry? This is the only thing I can think of? The fact that $expiry means 2 completely different things in the same get() api call is a trip hazard that needs flagging in the docs. I spent ages wondering why caching wasn't working and eventually stepped through to look at the SQL to get here.1 point
-
It has indeed solved the issue, thanks!1 point
-
Ok learning from the last 2 days: The action that I'm using uses the "angular" preset which has a slightly different syntax than what is listed on https://www.conventionalcommits.org/en/v1.0.0/ Using the conventionalcommits would be possible (https://github.com/TriPSs/conventional-changelog-action/issues/217), but that would mean we had to "npm install" some dependencies, which is not what I want, as the nice thing with this setup is that everything works out of the box with just adding one file to your repo. Memo: Breaking changes need to be written with a "BREAKING CHANGE: ..." footer to trigger a major version bump. The exclamation mark syntax like "feat!: ..." does not work. Thx @dotnetic for your help!1 point
-
For WordPress sites I used the Plugin Better Search Replace to replace hardcoded Urls when transferring Sql dumps from localhost to my live server and vice versa. For other CMS I just opened the Sql dump in Notepad++ and did a search/replace of Urls to match right host.1 point
-
Hello @ryan, I had to change some role names on an existing site – after a while I recognized changed behavior for some role related functions. What I found is that using roles in selectors doesn't work exactly the same as I see on other fields: $s1 = "roles=aaa"; $s2 = "roles=aaa|guest"; $s3 = "roles=aaa|guest|notavailable"; echo $users->find($s1); //works, returns some users echo $users->find($s2); //works, returns some more users echo $users->find($s3); //returns empty pageArray ! As soon as I do an "OR" with a role, that does not exist, it wipes out the whole result set. Is this the intended behavior? I guess not, but maybe you can tell me where I'm wrong. Thank you!1 point
-
Ryan has already responded to the Github issue and will merge the fix as soon as it can be confirmed. Passing along a PW API method call he shared that can fix this in case anyone that runs into this and wants to skip working in the DB directly.. $query->exec('RENAME TABLE tmp_field_body TO field_wvprofile_body'); Thanks @ryan!1 point
-
Confirmed renaming the tmp field table to the original table name solved the issue. Many thanks for your work!1 point
-
Fantastic work! That table does exist in my DB. As for DB table names being lowercase by default, that seems to conflict with the admin UI. If the field lets you enter uppercase names, but table names default to lowercase, I think this issue is pretty much guaranteed to happen. I think that because the UI has shown that uppercase letters are accepted and it's been that way for a long time then the solution would be for $config->dbLowercaseTables to default to false. That would preserve the behavior shown in the admin and fix the issue going forward. But, I too, have started to dig deeper. I did a quick search because I was curious about case-handling in MySQL itself and if there might be additional scenarios to consider. Database case sensitivity is dependent on the filesystem of the underlying OS. Windows is not case sensitive, Unix-like systems such as Linux are case sensitive, macOS is almost always the exception to that rule where it's a Unix-like system but HFS+ is not case sensitive and APFS can optionally be (but only at the time of formatting the disk) and is not by default. Even Docker on Mac looks like it struggles with this. So I'm wondering if this is an environment issue and having $config->dbLowercaseTables is true to mitigate potential issues. Regardless though, the admin UI/name field validation should reflect the current DB casing configuration. The better option would just be to eliminate using uppercase letters for fields in the future if it would act as a sort of protection for all environments.1 point
-
I did a little more digging too. It seems as part of the field rename process, the corresponding (old) table is temporarily renamed to tmp_field_yournewname, and then tries to rename this temp table to the correct new name: field_yournewname. This second part fails because the table already exists, so I believe this throws an Exception and you would expect the admin to re-render with an error notice. (Like it does with the normal duplicate field name error). However, since the underlying field's DB table has been renamed to its _tmp version, there's another exception, showing the error. At least I think that's what's happening. DB table names are lowercase by default ($config->dbLowercaseTables is true unless overridden), so 'Body' will try to create 'field_body'. @FireWire, you might find there's a tmp_field_body table in your DB, with all your content intact. Good to know there's a Github issue opened.1 point
-
There was nothing special in the setup, it's a very similar setup to what I usually use on sites. Really appreciate you looking into it and running some tests! This is it. It was the uppercase B in Body that I accidentally put into Name instead of Label that conflicted with another field named body. Really appreciate @Robin S @wbmnfktr and @iank working to figure out what happened, I don't have the time to troubleshoot right now (deadlines!) and you really helped out. If I didn't find out what happened I would be kind of uneasy about the website. Ideally I think it would be best if field names were restricted to lowercase, but that would be a big breaking change at this point. Many situations could cause this: Text intended for the Label could mistakenly be put into Name and all data is lost for that field (my case) A developer may be familiar with this bug, but not know or have forgotten that a field already exists with a name that will conflict Accidentally mistyping with a capital letter where a lowercase letter would have shown the appropriate duplicate field name error I have opened a Github issue for this bug.1 point
-
If all your variations (thumbnails and other variations) are corrupt you can delete them with the Pageimage Remove Variations module. The variations will be recreated next time they are requested.1 point