Leaderboard
Popular Content
Showing content with the highest reputation on 07/07/2023 in all areas
-
The new dev branch version 3.0.222 contains about 20 commits and 16 issue resolutions. In terms of new features, last week I mentioned some upgrades to WireHttp, and below are this week's additions: Multi-language month and day names The WireDateTime class (aka the $datetime API variable) has been updated to support multi-language month and day names. Now all month and days are translatable in the WireDateTime file (/wire/core/WireDateTime.php). So if you request any date in a format that uses month names or abbreviations, or day names or abbreviations, they now support multi-language, whether you requested it from the wireDate() function or the $datetime API variable. ProcessWire has long supported multi-language month and day names when using a PHP version prior to 8.1 and you've requested a strftime date format that uses them. But PHP 8.1 dropped the multi-language supporting strftime() function, without leaving a suitable replacement. PHP's IntlDateFormatter can't be relied upon since it's not always compiled with PHP. But as of PW 3.0.222, now we have a suitable replacement. Though it does require you to translate the 7 days and 12 months for file /wire/core/WireDateTime.php using ProcessWire's language translation tool. Note that unlike the previous strftime() solution, the new solution no longer requires you to use strftime() format codes and you can instead use regular date formats and they will be translated automatically. New conditional hooks that match by argument type Another new addition this week is support for conditional hooks that match by argument type. I think this is especially useful combined with ProcessWire's custom page class support. It enables you to make a hook apply only to methods containing arguments of a specific type. For instance, if you had a custom page class "ProductPage" for template "product" and you wanted to capture the "Pages::saved" event for pages of that type (ProductPage) you could do so like this: $wire->addHook('Pages::saved(<ProductPage>)', function($event) { $product = $event->arguments(0); /** @var ProductPage $product */ $event->message("ProductPage '$product->title' has been saved"); }); In addition to supporting class or interface names, you can also specify regular PHP types such as <array>, <string>, <int>, <object>, etc. For more details on this type of hook see the new Conditional hooks that match argument type section of the Hooks documentation. Thanks for reading and have a great weekend!9 points
-
RockShell v2.0.0 is out. It's been in development for quite a long time and I use it on a daily basis. This module is a little special, as it has to be placed in the PW root folder (not in /site/modules). From there you can then call the shell interface via "php RockShell/rockshell" You can then use the "symlink" command to create a symlink in the root folder. After that you can call rockshell via "php rock" in the pw root folder. I've made it as easy as possible to create custom commands - you only need one config() and one handle() method! https://github.com/baumrock/RockShell/6 points
-
Hello everybody ? and thanks for your patience! Finally ended my sabbath and updated the module with pull requests and fix for the apostrophe thingy. Also added missing PW namespace + Composer support. There you go!5 points
-
As a free solution for ProcessWire I would definitely recommend PrivacyWire. In my opinion it is the only viable solution at the moment. When that's not an option or more automation is needed, we tend to use Cookiebot. It's a paid service (they do have a free tier for small scale and limited requirements), but there are a few things that can make it worth the cost: It scans the site (as you mentioned) automatically and creates a list/table of used cookies, as well as identifies any cases where cookies are set without prior consent. At least here in Finland a list of cookies used on a site — including whether they are first or third party cookies, what they are used for, and for how long they are stored — is required. While one can of course keep such a table up manually, well... let's just say that especially for large and media-rich sites it's a whole lot of work. It has an automatic block mode that at least tries to automatically prevent the browser from loading anything that can set cookies. With PrivacyWire (for an example) you'll have to modify the markup of embedded script tags, iframe elements, etc. in order to load them only after consent has been given. It automatically generates and stores per-user consent history. At least here in Finland that is a necessary thing — site owners must be able to produce proof that the user has indeed given consent to storing data, and a separate registry is a must (said proof has to be available even if the user has cleared their cookies, localstorage, etc.) With paid plans it is very customizable. For an example we use a modified version of generaxion/cookiebot-accessible-template, since many of our sites need to be accessible. There are other services that do similar things, and I believe that some are cheaper than Cookiebot, but I have not had a chance or any need to properly dig into said other services. I'm only familiar with official guidelines and legislation as it has been implemented here in Finland, and also IANAL. Even with GDPR the actual implementation (and how that implementation is interpreted by officials) can vary from country to country ?4 points
-
Introduction to RectorPHP In the dynamic world of PHP development, code refactoring is an inevitable task, whether for code optimization or transitioning to newer PHP versions. RectorPHP stands as a vital tool, simplifying this often challenging process. So, what is RectorPHP? What is RectorPHP? RectorPHP, or Rector, is a revolutionary open-source tool created to automate the process of refactoring PHP code. Refactoring, in simple terms, refers to the modification of a software system's internal structure without changing its external behavior, ultimately leading to enhanced readability and maintainability. Built on the powerful PHP Parser library, Rector analyzes and manipulates PHP code at the abstract syntax tree (AST) level. This granular control allows for intricate adjustments, making refactoring a breeze. But Rector's capabilities don't end here. Its true strength lies in its role as an automatic code upgrade tool. RectorPHP as an Automatic Code Upgrade Tool RectorPHP's primary role is to transition PHP code from legacy standards to modern, efficient, and more secure versions. This transformation allows developers to maintain their codebase up to date, benefiting from the latest advancements in PHP development. How Can RectorPHP Upgrade Your PHP Code? RectorPHP provides a smooth and efficient roadmap to upgrade old PHP code to contemporary versions. Here's how: Installation The first step is to install Rector in your project. Given it's a composer-based project, installing is as simple as running composer require rector/rector --dev in your terminal. Configuration Next, Rector requires a configuration file (rector.php) to instruct it on what to refactor. This file, located at the root of your project, should specify the rule sets Rector should adhere to. For instance, the following configuration upgrades PHP code to PHP 8.1: <?php declare(strict_types=1); use Rector\CodeQuality\Rector\Class_\InlineConstructorDefaultToPropertyRector; use Rector\Config\RectorConfig; use Rector\Set\ValueObject\LevelSetList; return static function (RectorConfig $rectorConfig): void { $rectorConfig->paths([ __DIR__ . '/src' ]); // register a single rule $rectorConfig->rule(InlineConstructorDefaultToPropertyRector::class); // define sets of rules $rectorConfig->sets([ LevelSetList::UP_TO_PHP_80 ]); }; Refactoring With Rector installed and configured, it's time to initiate the refactoring process. Execute vendor/bin/rector process in your terminal, and Rector will begin refactoring your code, illustrating the changes as it progresses. Review and Test While Rector often delivers flawless results, it's still a good practice to examine the modifications it makes. Ensuring that the changes conform to your project's requirements and haven't led to any unforeseen behaviors is a smart move. To further ascertain that your system's functionality remains unscathed, it's advisable to run your test suite. Remember, these steps aren't strictly necessary, but they add an extra layer of safety to your refactoring process. Rector also provides a "dry run" feature, where it displays the proposed changes without actually modifying the codebase. This feature is useful to preview what Rector will do before allowing it to alter your project. Conclusion RectorPHP is an essential tool for PHP developers looking to modernize their codebase efficiently. By simplifying the refactoring process and offering a seamless upgrade path for transitioning to more recent PHP versions, Rector empowers developers to focus on crafting high-quality software. Utilizing Rector means keeping your PHP code in sync with the rapidly evolving landscape of PHP development.2 points
-
Monthly update: RockFrontend 3.2.2 is out ? Bug Fixes RockFrontend script tag in markup when not needed (25364be) add lattepanel again (had to temporarily remove it on previous release) Features add HumanDates library for better readable date ranges (1. Jan. 23 - 3. Jan. 23 ---> 1. - 3. Jan 23) don't load livereload in iframes and update minification only load RockFrontend.js if enabled2 points
-
Hi, Check utilities from @Robin S there is a lot of gems: https://github.com/Toutouwai/RepeaterImages And give a read on those articles: https://processwire.dev/processwire-responsive-images/ https://processwire.dev/building-display-options-processwire/ (Example 2) For the twig things, its easy to convert it to standard html markup.2 points
-
Guess DeQuincy is searching for something different than my module NoCoWoCo. My module just shows a consent box for enabling or disabling technical required Cookies e.g. used for booking form validation etc. and blocks the wire Cookie unless user gave consent. Also not really required for technical Cookies, my client wanted to have this feature just to be on the safe side . So my module does not disable other cookies like Youtube, Google fonts etc. on users choice. Guess he is more after something similar to this project on Github https://github.com/orestbida/cookieconsent. Have used a similar solution for a plain HTML5 site with no CMS as backend.2 points
-
@bernhardWish days would have 30 hours so I could use 6 for testing stuff like your RockFrontend* modules while still have enough time for family, day job and spare time :-). Thanks anyway, sometimes I will test all your modules for sure, as your Github repos are already a big inspiration from a coding perspective.1 point
-
@Divinorum Since you are trying to match a range of prices, it looks to me like you'd want an AND condition for that price_list.price rather than an OR condition? The AND condition in your selector would be: price_list.price>=15000, price_list.price<=20000 Assuming that price_list is a Page field that lets you select multiple pages, a selector like the above says this: at least one page in your price_list field must match price>=15000 and at least one page in your price_list field must match price<=20000. It doesn't say that they have to be the same page in that set matching both of those conditions. If you want to tell it that the same exact page in that set must match both of those conditions (which seems more useful here), then prefix an "@" to both of the conditions (see subfield selectors for more details): @price_list.price>=15000, @price_list.price<=20000 For a single-page selection field, this use of "@" would not apply, as there's only ever 0 or 1 pages in the set of selected pages. Note that there is no such thing as double pipes "||" for an OR condition in selectors (from your example), but there is such thing as using 1 pipe "|" to match one field or another, or one value or another. See the Selectors doc page for more details. Also check out selector OR-groups, which I don't think are useful here, but seems like you might have been thinking of something like it when using those double pipes.1 point
-
I installed SkyScraper profile (last commit from year 2013, not compatible with PW3) on PW 3.0.221 and loaded home page: 1.10 seconds: no cache enabled 1.00 seconds: built-in cache enabled 0.35 seconds: AIOM+ enabled1 point
-
This is one of the rare things that are not instantly intuitive to I guess 99% of my clients! Have you considered adding a PR @Robin S ? Imho that's really an essential feature, thx for creating and sharing it! Just added it to RockMigrations default profile ?1 point
-
If i understand your question right this module will help you: https://processwire.com/store/pro-fields/repeater-matrix/ As a part of the ProcessWire Pro Fields it is not free. You can create different types of repeater elements and the user can choose which one to use on each page. Its pretty cool!1 point
-
try dots $products = $pages->find("price_list.price=20");1 point
-
I have one more small suggestion to improve the function a bit ? Just replace the complete if inside the execute-endpoints.php file: if ($action === 'action-get-openapi') { [...] } With this: if ($action === 'action-get-openapi') { header('Content-Type: application/json; charset=utf-8'); echo json_encode($openApiOutput, JSON_PRETTY_PRINT + JSON_UNESCAPED_SLASHES + JSON_UNESCAPED_UNICODE + JSON_UNESCAPED_LINE_TERMINATORS); die(); } So Tracy is disabled on output and via the browser you can save the file directly as json. And Thanks for this nice update ? @Sebi1 point
-
@olafgleba As I understand it, you've got pages that live at /members/blog/<name> and you want them to be accessible at /blog/<name>. First thing is to make it so that the blog post pages ->url property reflects the URL you want them to use. You can do this with a hook in /site/init.php: $wire->addHookAfter('Page::path', function($event) { $path = $event->return; if(strpos($path, '/members/blog/') !== 0) return; $event->return = str_replace('/members/', '/', $path); }); Next, you want to make it so that ProcessWire will deliver those blog post pages at the /blog/<name> URL. You can do this either by enabling and handling URL segments on a /blog/ page, or you can use a URL/path hook, again in /site/init.php. I'm going to assume there is no /blog/ page, so a URL/path hook may be the best bet: $wire->addHook('/blog/{name}', function($event) { $name = $event->arguments('name'); $blog = wire()->pages->get("/members/blog/$name"); return $blog->id && $blog->viewable() ? $blog : false; }); Are those /members/blog/ pages are access protected from public users? If so, the above hook is not going to let them through because of the $blog->viewable() condition at the end. You could remove that, or better yet, replace it with a different condition: if($blog->isUnpublished()) return false; return $blog->id && $blog->template->name === 'blog-post' ? $blog : false; I can't remember at the moment if ProcessWire does another access control check on the returned page ($blog). So if you find it doesn't work returning the $blog page, try having it return $blog->render() instead.1 point
-
First off, I won't stop developing ProcessWire unless I'm dead. But lets say that one of you showed up at my door and shot me, and then I'm gone for good. This is free software and you don't get any guarantees there, no matter what CMS it is or how big the community or adoption of it is. But what you do get is the source code and permission to use it and do with it what you need to. There is far more security in that than any proprietary or commercial system. We should all feel very lucky that this project has attracted such a capable development community around it (more than any project I've ever seen), and there are several guys here that are fully capable of taking over the project if I go down in a hang-glider crash. I'm always reluctant to list off people because there are so many people that contribute to the core and I don't want to forget anyone. Suffice to say, I may hold the keys to the master GitHub account, but this is a project of many developers, at least 5 of which are fully capable of taking over the project if I kick the bucket. I'm certain that some of these guys could do better than me with it. Please don't take that as an invitation to show up at my door with a weapon. But I would suggest this may be better odds than with the bigger projects you'd mentioned. Lets also point out here that ProcessWire is not WordPress–it does not need daily updating in order to keep running. Most sites I build with ProcessWire are running the version they are launched with. With ProcessWire, you do not need to upgrade your site every time a new version comes out. You can generally upload it and forget it, and it'll keep running till the site as long as the server itself is running. What other CMS can you say that for? (I can't think of any) Personally, I think adoption of something like Drupal, Typo3, Joomla, etc. is more of a risk, because you are dealing with a legacy platform – you are adopting technology from 10 years ago. You are also adopting something that is a target for hackers and spammers. WordPress is perhaps the biggest target, and something I've very apprehensive to setup for clients. Ultimately when a company chooses to adopt a legacy platform because "it's what the clients know" or [more likely] what they themselves know, it's a lazy decision. It's not looking out for the clients' best interests, and it's pursuing mediocrity. When you pursue mediocrity, you pay for it in the long run. There is no better testament to that than the legacy platforms that agency seems attached to. 1-3 years after installing [Drupal/Joomla/Typo3/WordPress/etc.] for the client, they are going to be looking for "something different" in terms of the CMS (we all know this) and they won't be coming back to the same agency. The agency that thinks it's playing it safe is really just hurting themselves when they give their clients something tired and mediocre that anyone can give them. Instead, give them ProcessWire, and they'll know you are different and better (a secret their competition does not have), and they'll be a lifetime client.1 point