Jump to content

Leaderboard

Popular Content

Showing content with the highest reputation on 05/06/2024 in all areas

  1. I was dusting off my Awesome ProcessWire repo and updating it with more relevant information. One thing that bothered me is that the various links I have in there to forum posts may have changed, but this forum software correctly forwards it to whatever the latest URL is. While the forum doesn't expose an actual canonical URL for a post, I found this little hack to make it as minimal as possible. Let's say you have this URL: https://processwire.com/talk/topic/29951-weekly-update-%E2%80%93-26-april-2024-%E2%80%93-profields-table-v29/ That bothers my "OCD" and if the post title were to be changed, the URL would change accordingly, but I figured out you can chop off everything after the post ID and following dash and add an extra dash if you want a canonical-like, minimalized URL. It would look like this: https://processwire.com/talk/topic/29951-- (two dashes required)
    7 points
  2. @MarkE There's definitely a lot of potential for this to evolve over time. Another example is that it can edit any pages this way, not just children. For that reason, I put in a hook: ___getChildren($page) so that anyone can override what are the "children" for the page. If there is hierarchy, such as there would be if the selector "parent_id=$page" were changed to "has_parent=$page", then I agree the way repeaters do hierarchy could work here too. But I figure the best bet is to keep it simple, focused and straightforward at first to get to a stable version 1, and then start evolving it to do more after that, if there's interest.
    5 points
  3. Padloper 009 I am pleased to announce the release of Padloper 009! It has been a minute! I apologise for the delay. Padloper 009 introduces a number of new features, bug fixes (especially in Multilingual sites) and improves overall code efficiency. Credits Before I get into the details, I would like to say massive thanks for all who have contributed to this release in various ways. You have contacted me via the forums, via PM and via email to report bugs, test Padloper and suggest and sponsor new features. In particular, I would like to thank (in no specific order) @Spinbox, @alexm, @joe_g, @ank, @csaggo.com, @Jan Fromm, @Pete, @Sonia Margollé and @kalimati. Whilst I will not name those who contacted me privately, please accept my gratitude for your help. Apologies if I forgot to give anyone a mention! Massive thanks to @ryan for ProcessWire. Padloper 009 is the most battle-tested Padloper yet! It has been tested and developed on high volume sites, sites that require lots of customisations and multilingual sites whose default language is not English. This robust development has helped fix bugs that I would not have been aware of otherwise as well as new ideas and features to improve the API, workflow and GUI of Padloper. Many of the suggested features have made it into this version. A few others are planned for the future. There is a lot to talk about in this version. Below I’ll just give a summary of the changes and where necessary, create separate topics to discuss some of the new features. Although Padloper 009 has undergone thorough testing, there might, inevitably, be some bugs. If you find one, please let me know in the forums under a separate topic. Thanks! Changes Features Home Customisable dashboard. You can render your own dashboard by creating a template partial named ‘padloper-process-render-shop-home.php’ and placing it at ’/site/templates/padloper/backend/padloper-process-render-shop-home.php’. Please see this thread for more details. Orders Customisable single order view. You can render your own dashboard by creating a template partial named ‘padloper-process-render-orders.php’ and placing it at ’/site/templates/padloper/backend/padloper-process-render-orders.php’. Please see this thread for more details. Order status actions: Can be applied manually for order, payment and shipping status. Quick filters e.g. ‘open’, ‘cancelled’, ‘abandoned’, etc. Products Configurable pricing fields. Sales and Normal Price (e..g WooCommerce) vs Price and Compare Price (e.g. Shopify). Please see this topic for more details. Categories can optionally be named ‘Collections’. Configurable via ‘/admin/shop/configure-padloper/’. Bulk clone existing products. Allow duplicate titles for products. Discounts (new) 4 discount types: Orders, products, free shipping and BOGO (Buy One/Get One - unfinished; see below). Can be applied manually or automatically at checkout. Please see this thread for more details. Add/remove via ‘/admin/shop/configure-padloper/’. Part sponsored by Nifty Solutions. Thanks @Pete! Customers and Customer Groups (new) Customer creation and management. Please see this thread for more details. Customer Groups. This feature will be expanded in the future. Please see the above thread for more info. Add/remove via ‘/admin/shop/configure-padloper/’. General Settings Redone interface Add ‘from email’ settings.. Add bank details settings.. Add order ‘least and most’ sales thresholds for orders’ quick filters. Settings for ‘low stock’ and ‘price fields’ for products. Add tab ‘user interface’ with settings for shop navigation (can have side menu and/or dropdown navigation) and search features (can use quick filters and/or advanced filter). Other Backend Quick filters on various dashboards. Custom Dashboards for Home and Orders. More to be added in future. Frontend Custom shop root page. This allows you to move product-related pages and legal pages to live under a frontend-accessible page. Configurable via /admin/shop/configure-padloper/. Please see this topic for more details. For instance, /myshop/products/, /collections/, /products/, etc. This means you can directly access products on the frontend using their real paths/urls instead of using URL segments. This setting can be changed anytime via configuring Padloper at /admin/shop/configure-padloper/. Custom URL segments for checkout out. E.g. instead of /checkout/success/, /checkout/confirmation/, etc., you can have custom, multilingual segments, e.g. /checkout/order-success/, /checkout/tilaus-menestys/, etc. Miscellaneous Various UI improvements. Dashboards tables sorted by title by default. Breaking Changes Template partials for the frontend have been moved from /site/templates/padloper/ to /site/templates/padloper/frontend/. Deprecated ‘Search Feature’ on the home dashboard has been removed. Use ProcessWire in-built search instead. Padloper hooks into it to group padloper related results. PadloperProcessOrder::orderSaved now becomes PadloperProcessOrder::orderSavedHook.The new approach is to have all hooks in one please for easier maintenance and usage. Bug Fixes Please see the bug fixes topic. How to Get It Padloper 009 is available at https://processwireshop.pw/products/padloper/. For those renewing subscriptions, you will have to wait a bit, apologies. I am finalising work on renewal codes. I am hoping this will be ready by tomorrow. Any issues with the (revamped ?) site please let me know ?. Upgrading This is a major upgrade. Lots of code has been moved around. Best way to upgrade files is to empty the contents of the root Padloper folder and upload the contents of the new version there. There are no data model changes affecting existing features but as always, back up your site(s) first! Next Steps In addition to fixing any bugs that show in 009, these are the plans for the next 3-6 months, possibly more, in order of priority. No new features will be introduced until these are completed. Documentation Documentation will cover all topics including installation, backend and frontend use and the API. ‘How to guides’ will consist of short videos with corresponding textual content on a dedicated Padloper site. Discounts Finish work on the Buy One Get One (BOGO) Discount and automatic discounts. Gift Cards Finish work on Gift Cards. Road Map I will talk about this when the ‘next steps’ tasks have been completed. Thanks!
    4 points
  4. I guess I'm just becomming really lazy as I age, and this tutorial can be taken as a sign of my growing sloth. I have a Yubikey that I use as my 2nd factor on a localy hosted PW site. And I've become tired of typing my admin username + password and hitting enter/clicking Submit + then having to tap the Yubikey to log in. I know, it's a local install, and I could just turn off my 2FA, but then I'd still have to type the username and password, and I'm too lazy even for that now (plus, I've started to hate passwords.) I'd really rather just tap the yubikey to be logged in! As PW's so hookable, I figured it would be pretty easy to modify the login process to allow me to do this, just for this site (well, maybe not just this one). Sure enough, it turned out to be pretty simple - though I do not recommend trying this on any sites hosted in the cloud. Firstly, you'll need the TfaWebAuthn module installed on the site, and have configured it on your superuser account. Once you are logging in successfully with that, add the following to site/templates/admin.php... /** * If there is only 1 superuser with TfaWebAuthn set up on the site, * and if the username is empty on login submission, we change the login_name * to the superuser's account name, and the login_pass to a dummy value to * allow the Session::authenticate hook to be called. * * Although the Session::authenticate method will fail we will hookAfter it * and pretend that it didn't. That will start 2FA credential collection * allowing us to proceed with just that protecting the account. * * For local installs where I have a YubiKey, this will be good enough. */ wire()->addHookAfter("ProcessLogin::loginFormProcessReady", function($event) { $uname = wire()->input->post->login_name ?? ''; if ('' === $uname) { $super_role_id = wire()->config->superUserRolePageID; $supers = wire()->users->find("roles=$super_role_id, tfa_type=TfaWebAuthn"); $num = count($supers); if (1 === $num) { $super = $supers->eq(0); wire()->input->post->login_name = $super->name; wire()->input->post->login_pass = 'dummy_password'; } } }); wire()->addHookAfter("Session::authenticate", function($event) { $super_role_id = wire()->config->superUserRolePageID; $supers = wire()->users->find("roles=$super_role_id, tfa_type=TfaWebAuthn"); $num = count($supers); if (1 === $num) { $user = $event->arguments(0); $super = $supers->eq(0); if ($user->id === $super->id && 'TfaWebAuthn' === $user->hasTfa()) { $event->return = true; // Override earlier failed authentication for this user } } }); As long as you leave the initial login details blank, all you need to do now is hit enter (or click Submit) and then tap the Yubikey to be logged in. Nice :)
    4 points
  5. I recently had the following need : For pages of a given template (named page-post-operation), I had to check if a certain field value had changed (a checkbox field named postReadyForPublish) and execute some logic if that was the case (in my case, send an e-mail to an admin user with proper rights to publish it). I thought, at the beginning, that it would be a little bit tricky as I needed to compare the value of this field for the previous version and the new version of the page. And it actually was not tricky. Kind of... ? So this is the hook I put at the beginning of the /site/templates/admin.php file (as it’s only useful in the admin part). $wire->addHookBefore("Pages::saveReady(template=page-post-operation)", function($event) { $page = $event->arguments(0); $oldPage = $this->pages->getFresh($page->id); // this is the tricky part if( $page->postReadyForPublish && !$oldPage->postReadyForPublish ){ // logic goes here } }); When you retrieve the previous version of the page in the DB, make sure you use the getFresh method. Otherwise, you will get the date in the cached version of the page, which are immediately saved, meaning that $oldPage and $page would have the same field values. Hope this may be useful to somebody else.
    4 points
  6. Or when using Custom Page Classes + MagicPages you have your code where it belongs (if it's for the "home" template then it's in the HomePage.php file) and avoid hook hell in site/ready.php // site/classes/HomePage.php class HomePage extends DefaultPage { use MagicPage; public function editForm($form): void { $f = new InputfieldMarkup(); $f->label = 'Help'; $f->value = 'Foo bar baz!'; $form->prepend($f); } }
    3 points
  7. In addition to the great suggestion from @Nicolas, you can also do it by prepending a Markup textfield to the edit form for just that particular template. Here's more code - I'd put this in site/templates/admin.php as this is only an admin feature. $pages->addHookAfter("ProcessPageEdit::buildForm", function($event) { $form = $event->return; $id = (int) wire("input")->get("id"); if (!$id) { return; } $editedPage = wire("pages")->get($id); if ($editedPage->template->name === "home") { // CHANGE TEMPLATE NAME HERE $f = wire()->modules->get('InputfieldMarkup'); $f->label = "Notes"; $f->value = "<p>Your HTML Notes in here.</p>"; $form->prepend($f); } });
    3 points
  8. Hi, Using ProcessWire notice system you could do something like <?php // In /site/ready.php $wire->addHookAfter('ProcessPageEdit::execute', function (HookEvent $event) { $pageEdit = $event->object; $page = $pageEdit->getPage(); if ($page->template == 'home') { $this->wire('notices')->add(new NoticeMessage("Hello World")); } });
    3 points
  9. From the Rock Monthly newsletter: RockPageBuilder v5.4.2 We have now an API to save settings: $block->saveSetting('image-size', 'S'); Docs about Frontend Editing have been improved. Fixed "$root not defined" bug
    2 points
  10. From the Rock Monthly newsletter: RockShell v3.0.0 Folders are now protected from direct access via .htaccess thx to a PR from @netcarver (but I don't think it was a security risk before) @netcarver also suggested to change the folder structure. This might break some commands, so I bumped the version to 3.0 (it might work without any changes though!) Made wget quiet in pw:install command as requested by @netcarver
    2 points
  11. Nice - I'll be able to make use of that at PWGeeks next time I update it. Thank you for the tip.
    2 points
  12. Hi, honestly for this kind of thing i use one of those two modules ? https://processwire.com/search/?q=runtime&t=Modules Robin's one is a little more recent but both work fine have a nice day
    2 points
  13. Hey @TomPich I think what you did can also be done like this: https://processwire.com/blog/posts/new-ajax-driven-inputs-conditional-hooks-template-family-settings-and-more/#new-conditional-hooks $wire->addHookAfter('Page(template=order)::changed(order_status)', function($event) { // execute some code when "order_status" changes on "order" pages. });
    2 points
  14. @Robin S @Mats @Marty Walker @ryan Pull request is in for this fix.
    2 points
  15. Version 1.3.7 is out This version comes up with some new additions as discussed in this forum in the last time. To check out what is new, please read the changelog.md As always, please keep in mind, that this is a new version with a lot of changes. I have tested almost all scenarious, but there could always be an unwanted behaviour. So keep an eye, that everthing works as expected. Otherwise please write an issue report (here or directly on GitHub). Have a nice week!
    2 points
  16. This is my first module. It is primitive, like my neighbor who loves to fire up his new Makita breaker hammer after 21:30h. Please, feel free to do whatever you want. I don't promise I will add better functionality but maybe... If you do, please ping and send me back. Thanks! It loads every page on the backend. It calculates the text width in two fields you choose on the configuration page.. If there are any updates, I will post them here. Happy ProcessWiring! PS: These measurements are specifically for desktop and Google's SERP (Search Engine Results Page). UPDATE on 15 May 2024: Google started to calculate (truncate) the meta title for 20px Arial yesterday. The Module has been updated. Here is the link to download/install the latest version: https://processwire.com/modules/seo-text-width/ EDIT: The version 0.0.5. Added two dropdown fields on the configuration page of the module. PROVE IMAGE: You can check the meta title, which was measured with 18px Arial and it was less than 512 pixels.
    1 point
  17. This module facilitates quick batch creation (titles only or CSV import for other fields), editing, sorting, deletion, and CSV export of all children under a given page. You can even provide an alternate parent page which allows for editing of an external page tree. http://modules.processwire.com/modules/batch-child-editor/ https://github.com/adrianbj/BatchChildEditor The interface can be added to the Children Tab, or in a new dedicated tab, or placed inline with other fields in the Content tab. Various modes allow you to: Lister - Embeds a customized Lister interface. Installation of ListerPro will allow inline ajax editing of displayed fields. Edit - This allows you to rename existing child pages and add new child pages. It is non-destructive and so could be used on child pages that have their own children or other content fields (not just title). It includes the ability to quickly sort and delete pages and change page templates. Also allows full editing of each page via a modal dialog by clicking on the page name link. This is my preferred default setup - see how it replaces the default Children/Subpages with an easily addable/editable/sortable/renamable/deletable list. Note that the edit links open each child page in a modal for quick editing of all fields. Add - adds newly entered page titles as child pages to the list of existing siblings. You could create a list of pages in Word or whatever and just paste them in here and viola! This screenshot shows the editor in its own tab (name is configurable) and shows some of the CSV creation options. Update and Replace modes look fairly similar but show existing page titles. Update - Updates the titles (and any other fields if you enter CSV data) for the existing pages and adds any additionally entered pages. Replace - Works similarly to Add, but replaces all the existing children. There are checks that prevent this method working if there are any child pages with their own children or other content fields that are not empty. This check can be disabled in the module config settings, but please be very careful with this. Export to CSV - Generates a CSV file containing the fields for all child pages. Fields to be exported can to fixed or customizable by the user. Also includes an API export method. Populating fields on new pages In Add, Update, and Replace modes you can enter CSV formatted rows to populate all text/numeric fields, making for an extremely quick way of creating new pages and populating their content fields. Predefined Field Pairings Like the field connections setup from Ryan's CSV Importer, but defined ahead of time so the dev controls what columns from the CSV pair with which PW fields. This is especially powerful in Update mode giving editors the ability to periodically import a CSV file to update only certain fields on a entire set of child pages. These pairings also allow for importing fieldtypes with subfields - verified to work for Profields Textareas and MapMarker fields, but I think should work for most others as well - let me know if you find any that don't work. Access permission This module requires a new permission: "batch-child-editor". This permission is created automatically on install and is added to the superuser role, but it is up to the developer to add the permission to other roles as required. Config Settings This module is HIGHLY configurable down to setting up custom descriptions and notes for your editors. You define one config globally for the site and then optionally you can define completely custom configurations for each page tree parent on your site. There are too many settings to bother showing here - you really just need to look through all the options and play around with them!
    1 point
  18. I logged into Google Search Console last night. For the umpteenth time, I received the message: "Fixes failed for Page indexing issues - Page with redirect." I am trying to get non-www URLs and use the default htaccess file (trying to keep up with the updates). Problem - Google scans the website URLs in this particular order, and chaining (which is The problem) via htaccess happens: http://www.example.com -> https://www.example.com -> https://example.com Fix: While I do not know how to write directives in the .htaccess, I spent hours to find a solution and finally succeeded. RewriteEngine On RewriteCond %{HTTPS} !on [OR] RewriteCond %{HTTP_HOST} ^www\. [NC] RewriteRule ^ https://example.com%{REQUEST_URI} [R=301,L,NE] However, as I mentioned, I'm unfamiliar with the .htaccess file, and I am 100% sure that this could be written with a wild card. So, on this occasion, by default, can we have an option to avoid chain redirections of URLs?
    1 point
  19. Hey all! This is a module to enhance forms built using the Pro FormBuilder module by providing the ability to submit them in place using AJAX and HTMX. FormBuilderHtmx works in harmony with FormBuilder by handling front-end rendering and AJAX and lets FormBuilder manage form configuration and processing. FormBuilderHtmx provides a drop-in replacement for the $forms->render() method and provides all native features and behavior (and adds a few extra superpowers to boot). Noteworthy features: Zero configuration, install and render AJAX powered FormBuilder forms immediately Render multiple forms on the same page. Supports both multiple instances of the same form or different forms. Each form is processed independently. Non-intrusive, can be used alongside FormBuilder's native rendering methods and does not modify core module behavior Perfect for forms embedded in popups and modals Does not conflict with styling and other JavaScript already in-place, only handles the form submission/response loop Automatically disables the `Submit` button on submission to prevent duplicate requests Provides the ability to add a custom 'spinner' shown when a form is being processed Gives you the ability to add additional HTML attributes to your FormBuilder <form> element. Add additional custom functionality using HTMX attributes, hook into form actions with your JavaScript, or even add AlpineJS directly to your forms. Compatible with FieldtypeFormSelect, let users choose which forms to embed, your code determines how they are rendered Uses HTMX, a stable, powerful, and tiny (14kb gzipped) library, installation documentation available here This module is BYOH (Bring Your Own HTMX) in that the HTMX library is not included or available within this module. This ensures long-term stability by not locking FormBuilderHtmx to external asset versioning. FormBuilderHtmx uses stable core HTMX features so use the library version that works for you and confidently add this module to both new, existing, and future ProcessWire applications. In some instances CSRF protection may need to be disabled to submit forms with this module. Just test your forms and you're good to go. Using this module is truly easy. <!-- Replace the native $forms->render() method with $htmxForms->render() --> <?php $htmxForm = $htmxForms->render('your_form_name') ?> <!-- Use native ProcessWire properties and methods as usual --> <?php echo $htmxForm->styles; echo $htmxForm->scripts; echo $htmxForm; ?> Presto. You can optionally include a helpful 'spinner' or activity animation that will be showed to users while their form request is being processed. Check out these ready-to-go examples you can use in your projects. <style> /* Add these styles to your CSS, the `.htmx-request` must be present as shown here. Be sure to include any CSS your 'spinner' may need, and style everything as desired */ .activity-indicator { display: none; } .htmx-request .activity-indicator, .htmx-request.activity-indicator { display: block; } </style> <!-- Optional second argument matches that of the $forms->render() method for pre-populated values The third argument is the CSS selector matching your 'spinner' element --> <?= $htmxForms->render('your_form_name', [], '#indicator-for-the-form') ?> <div id="indicator-for-the-form" class="activity-indicator"> <span class="spinner"></span> </div> Presto (again) Check out the documentation for detailed usage and other available features. Pull requests and issues filed on Github are welcome, or drop by here to get some help! Install as a ProcessWire module Install using Composer Download from the FormBuilderHtmx Github repository . Cheers!
    1 point
  20. Hi, First of all, great work @jploch! I'm testing pagegrid to integrate it to site with custom theme. By custom theme I mean that the site's appearance is already built manually. So I would like to use PAGEGRID to give users an easy way to handle content in the page. I've now installed PAGEGRID and configured it. But the problem is that when I edit the page with PAGEGRID it also load the manually built appearance. The page is built using append and prepend files. Any ideas how to do this correctly?
    1 point
  21. With the current project that I'm working on, there's eventually going to be an enormous amount of data to edit within it (in ProcessWire), and so I've been looking for ways to optimize and facilitate the editing experience. The goal is to save the people editing as much time as possible, and reduce the number of steps necessary to make common edits. This is what motivated the recent Table field updates. The is also what motivated a new module I'm working on called PageEditChildren. The PageEditChildren module takes the existing "Children" tab in ProcessWire's page editor and replaces it with a new one that lets you edit all of the child pages inline, directly from the parent page. For specific cases, such as the one shown in this video (below), this provides a more convenient way to edit multiple pages at once. It can significantly reduce the amount of back-and-forth between the page editor and the page list, or multiple page editors, keeping it all in one page editor session. Likely you would use this module to replace the "Children" tab on just some (not all) pages. Specifically, pages where the relationship between parent and children is one where they are often edited as a group. This is a fairly common use case in ProcessWire, and one where this module can save you a lot of time. From an editing standpoint, it has a lot in common with repeaters. Other modules that have some crossover are PageTable (core) when configured to create/edit children pages, and BatchChildEditor. Both use page editors in modal windows to accomplish editing children, a different approach than PageEditChildren, which keeps it all part of the single page editor. Though BatchChildEditor can edit title and status (hidden/unpublished) inline, and supports CSV export/import options, among other useful tools. All of these modules are worth consideration when there is a need to optimize the editing experience between parent and children. This is just an early preview of PageEditChildren, so I'm going to work on the module and test it out a bit more before releasing it. But it could be ready to share as soon as next week. Supporting file/image and repeater fields in this module required some minor core improvements, which are in this week's core updates. I'm interested to hear your thoughts on whether this would be useful in your sites as well? More next week. Thanks for reading and have a great weekend!
    1 point
  22. @kongondo nice!! I saw your update. I'll await the link for renewal as per your update. Great work!! ??
    1 point
  23. Thanks for the updates, Bernhard. Seems like I somewhat monopolised things this month :)
    1 point
  24. From latest Rock Monthly newsletter: RockFrontend v3.14.0 LiveReload does now work on Tracy's bluescreen! That means if you introduce an error that throws an exception (like a typo that causes a call to undefined function...) you don't have to leave the IDE and reload the browser. Simply fix the bug and your browser will refresh! The great AJAX Endpoints feature has been improved thx to @netcarver We now have LiveReload on AJAX Endpoint debug screens! We now support relative urls in the svgDom() method + improved docs. Sitemap tools have been improved and multilang support has been added, see docs: https://tinyurl.com/ywflthta SEO tools improved: canonical tag now by default!
    1 point
  25. @Nicolas you're right and it's one of those things that makes it so great without speaking of all those crazy guys here who never stop helping while writing great addons ?
    1 point
  26. Just curious, can that also be done with page classes + magic pages, @bernhard ?
    1 point
  27. Woaw... Even simplier ! I didn’t know about the Page::changed hook. ? Thanks Bernhard. EDIT: I just realized that, in my use case, it wouldn’t be enough. I don’t want to execute the logic if the field has changed, but [IF the field has changes AND the new field value is true]. But still, this hook is great and may cover 90% of use cases.
    1 point
  28. @Entil`zha Hi. By default PAGEGRID renders the whole template inside the backend/fontend. But you can easily customize that. <?php if(!$pagegrid->isBackend() ) { // render things only for the frontend // Eg. Header, Sidebar } // render pagegrid $pagegrid->styles($page); $pagegrid->renderGrid($page); ?> If you are using markup regions you can have the check from above inside your _main.php file. To quickly disable ProcessWire’s automatic append/prepend of file “_init.php” and “_main.php” for a template, you can put this function at the top of your template file. $pagegrid->noAppendFile($page); Note that this will disable the append and prepend files from this template also for the frontend. You can also do it the other way around and disable it globally by uncommenting the lines $config->prependTemplateFile and $config->appendTemplateFile in the config.php file off your site folder and include the files manually on the templates where you want them..
    1 point
  29. Even if you enter that manually : "sameAs" : [ "https://www.facebook.com/company", "https://www.instagram.com/company", "https://www.linkedin.com/company" ] the browser still skips the line breaks (as shown in the console). I guess you can’t override this behaviour.
    1 point
  30. Not sure where the time went! We got there finally! ?
    1 point
  31. @netcarver, your version works great for the two examples I gave in the GitHub issue. Thanks!
    1 point
  32. Glad that worked! Fix has been pushed to main. Thanks for finding, reporting, and testing @wbmnfktr Download latest on Github
    1 point
  33. Apologies all! I did not keep my word! A number of things beyond my control happened but now I am back. Shop is open. I will post an update tomorrow about MM Next. Thanks.!
    1 point
  34. Great addition @ryan Had you thought about dealing with hierarchies in the same way as repeaters? Then there would be almost no need to use the separate children tab.
    1 point
  35. 1 point
  36. @ArklogicFor actual PW versions, just put your live config settings into config.php and your local development settings into config-dev.php and don‘t upload the dev config to your live site. This works quite well for small sites/teams. In config-dev.php you could use plain PHP to read from .env or add switches to reflect different stages based on a variable, flag etc.
    1 point
  37. That's INP then. I guess. New performance metric. https://web.dev/articles/inp And you can already check that here: https://page-speed.dev/
    1 point
  38. Ok, sorry, clickbait ? Hooks are great! But sometimes, there are even better solutions: I'm cleaning up RockForms to finally release it ? I have some pages that are only for storing data (like form entries and such), so I don't want them to be editable, not even for superusers, as I control them solely via code in my module. -- Solution 1 -- With a regular hook that would look like this: <?php // site/ready.php $wire->addHookAfter("Page::editable", function($event) { $page = $event->object; if($page instanceof \RockForms\Root) $event->return = false; }); That's quite nice, but this approach has some drawbacks: First, sooner or later you might end up with hook-hell in ready.php; That's not ideal and really hard to debug on more complex projects. Second, as we are defining the hook with a callback in a non-OOP style these hooks get a LOT harder to debug! Have a look at tracy's debug panel: The second highlighted hook is the one coming from ready.php and it does not show any helpful information whereas the first one does show clearly that the hook is attached in RockForms\Root in the method "hookUneditEntries" (it should be hookUneditRoot, but I made a mistake when copy-pasting, sorry ? ). -- Solution 2 -- So the next best solution IMHO is using custom page classes! Then you get OOP style and a lot better structure for your project with really very little effort! Just create a file in /site/classes and that's it. Now to attach hooks directly in custom page classes you have to do one additional step. You can watch my video about this if you are interested. If not, head over to solution number 3 which is even simpler ? This solution might look something like this: <?php namespace RockForms; use ProcessWire\HookEvent; use ProcessWire\Page; use RockMigrations\MagicPage; use function ProcessWire\wire; class Root extends Page { use MagicPage; public function init() { wire()->addHookAfter("Page::editable", $this, "hookUneditRoot"); } protected function hookUneditRoot(HookEvent $event): void { $page = $event->object; if (!$page instanceof self) return; $event->return = false; } } This might look like a lot more code, but it's a lot better in the long run in my opinion as things that are related solely to the root page are inside the Root.php file of my module/project. -- Solution 3 -- But then I remembered: As our "Root"-page is a custom page class and PW checks if the page is editable or not by calling $page->editable() we can simply override this method like so: <?php namespace RockForms; use ProcessWire\Page; class Root extends Page { public function editable() { return false; } } You don't even need to make it a "MagicPage" because you don't need an init() method to attach any hooks. Now it's only very little additional code compared to a hook in ready.php but with a lot cleaner setup ? It's not a new invention, but I thought I'd share it nevertheless. Maybe it's helpful for some and maybe it's a good reminder for others, that even hooks are sometimes "overkill" ?
    1 point
  39. Just to add another solution to the original question, this is how I hide not editable pages in admin tree: $this->addHookAfter('Page::listable', isPageListable(...)); function isPageListable(HookEvent $event): void { if ($event->page->path == "/") $event->return = true; else $event->return = wire()->user->hasPermission("page-edit", $event->page); }
    1 point
  40. You definitely should give them another try @AndZyk. Since your first post a lot of things changed. Am I really experienced? Maybe kind of. Ask me this when I finished the next 100 projects with lots of rich snippets/schema-markup. ? My examples and code snippets wouldn't be any different than any other resource out there. I really love this tool: https://technicalseo.com/seo-tools/schema-markup-generator/ You can create several kinds of markup as an example and implement them in your project. Those examples are a great starting point for everything. From breadcrumb to review or events. Test your markup over at Google and do what they want you to optimize in your markup: https://search.google.com/structured-data/testing-tool/u/0/ Check the schema.org definitions and guides for more details: http://schema.org/ Set up Google Search Console, check your markup with it and let Google crawl your optimized sites. Get reportings on errors and fix them fast. As written before: start with small parts of site (if possible) check results every 2 days for several weeks don't try to trick Google don't fake reviews don't fake review-counts or anything else If you are into Local SEO do the basics and create company and localBusiness markup with everything you can (logo, social profiles, site search, opening hours, ...), connect to Google My Business. Feel free to contact me or ask whatever you want. It's easier for me to answer a question right now.
    1 point
×
×
  • Create New...