Leaderboard
Popular Content
Showing content with the highest reputation on 07/18/2024 in all areas
-
Fridays are always the days when I'm full-time on ProcessWire. Other days I may be doing client work, or ProcessWire, just depending on the week. This week it's been mostly client work. And I just learned that I'll have to be out of the office tomorrow (Friday) for a family commitment. So I'm writing this weekly update today instead, and just sent out Teppo's great ProcessWire Weekly newsletter with ProMailer today (usually it gets sent Friday). Because of this change in schedule, I don't have much new to report just yet. Instead, I wanted to start talking a little about future plans, so here's a few ideas. I think we should get another main/master version out, perhaps by September. Following that, I thought we should focus on ProcessWire 3.1, or maybe it's time for version 4. What would be in this next major version of PW? For starters, we'll finally drop support for older PHP versions and start taking advantage of all that's been added new newer PHP versions (8+). This will involve lots of updates to the ProcessWire core code base, while remaining 100% API compatible with PW 3.x. I thought that would be a good starting point into our next major version at least. In addition, we'll likely be trimming some things out of the core and into separate non-core modules, such as FileCompiler, CKEditor, the two legacy admin themes, and a few rarely used Textformatter modules. Most likely we'll also have an overhaul of this website and some nice improvements to our primary (Uikit) admin theme to accompany the next major version as well. There will be plenty more too, but this is what I've been thinking about so far. Your feedback is welcome. Thanks for reading and have a great weekend!2 points
-
I think this might not be too hard to implement. Currently there's just \site\templates, but if there were something like site\[theme]\templates, then it would be possible to have multiple versions of templates. This could be potentially useful during development to test out a new theme while retaining the existing one, and if it were linked to roles so it's possible to specify what theme a given role uses, it would make it easy to provide completely different looks for different users. It could allow A/B testing with users to determine design preferences. This would also be useful in a multisite scenario if different sites use common backend templates, but use a different theme to present on the frontend.2 points
-
@Alpina, the OP is asking how to output the field values of a page in the order that the fields are positioned in the page's template. To get the fields in order you can use $page->fields, and you can then iterate over those fields to get the field values from $page via the name of each field. As developer you generally have control over both the template within the PW admin and the template file that outputs markup. So if you have a template with fields "title", "body" and "gallery" then I think the normal way to control the order of these fields is by structuring the markup you want within the template file and then getting each field value individually by name. <h1><?= $page->title ?></h1> <div class="text"> <?= $page->body ?> </div> <div class="gallery"> <?php foreach($page->images as $image): ?> <img src="<?= $image->url ?>" alt="<?= $image->description ?>"> <?php endforeach; ?> </div> If later there is a decision to place the gallery before the body text then you change the order of the markup in the template file. You might also change the order of the fields within the template in the PW admin so that it reflects the order that fields are output in the frontend, but that's a separate decision and moving the fields in the PW admin doesn't actually define the order of output. Alternatively you could have no fixed order of output within the template file and use the order of the template fields as defined in the PW admin. <?php foreach($page->fields as $field): ?> <?php $value = $page->get($field->name); ?> <?php if($field->name === 'title'): ?> <h1><?= $value ?></h1> <?php elseif($field->name === 'body'): ?> <div class="text"> <?= $value ?> </div> <?php elseif($field->name === 'images'): ?> <div class="gallery"> <?php foreach($value as $image): ?> <img src="<?= $image->url ?>" alt="<?= $image->description ?>"> <?php endforeach; ?> </div> <?php endif; ?> <?php endforeach; ?> I just think this is a less practical approach and makes the template file harder to understand.2 points
-
Would be great to see .env support. I think this base change would level up ProcessWire and make it an increasingly viable application framework that fits into modern workflows. I think this would be a great idea. It would greatly help module development where modifying or appending behavior to existing elements is needed. I could see that having been useful when developing my Fluency module. I'll throw a thought in about multi-site capability after considering multi-tenancy for a Laravel project using a module. May be a nice feature but if there's a tradeoff for future features and development speed due to maintenance overhead, both for ProcessWire core and modules, it may not pencil out. I know it's not apples to apples, but creating two sites and a private API between them has worked for me in the past.2 points
-
I thought I would share this as I am finding it increasingly useful and am often using it to replace the standard PW modal. It allows display and customisation of admin page in front end as well as back end via a modal. In the modules library at https://processwire.com/modules/admin-in-modal/ . Also here https://github.com/MetaTunes/AdminInModal This module provides a Page hook method ($page->aim($array)) for front-end use and a similar Inputfield hook (for back-end use) to render a link to a lightbox modal containing an admin page. Optionally, class styling can be passed, otherwise default button styling is supplied. Full list of options and defaults for the array is : 'href' => null, // the url for the linked page (including any required GET params) 'text' => '##', // the text that will appear in the link 'class' => "uk-button uk-button-primary", // any suitable styling for an <a> tag 'width' => '90%', // size for iframe 'height' => '95%', 'header-text' => 'Save required changes before closing -->', // Text to appear above top left of modal 'save-head-button' => '1', // Adds a save button at the top of the modal. Set to '0' to omit. 'suppress-notices' => 'messages', // e.g. null/[]: no suppression, 'messages': suppress messages, 'warnings messages': suppress warnings & messages, 'errors': suppress errors 'close-button' => '1', // set to '0' to remove close button (but you'd better be sure you know how the modal will be closed!) 'redirect' => '.', // url to redirect to after closing the modal - default is to reload the current page (use redirect => '' to suppress) (From v0.3.0, these defaults can be configured in the module settings). For front-end use, the lightbox will only be rendered if the page is editable by the current user. Configure editability of the page by calling a hook after User::hasPagePermission The lightbox is provided by the Magnific popup, which is in the PW core. Although I have used it quite a lot, I cannot say that it has been fully tested, so is alpha at this stage and should be used with care. It is the user's responsibility to check that it suits their needs. Because it allows access to the admin back-end, particular care should be taken to restrict page-edit access.1 point
-
Please check out the new version on the dev branch which will be merged begin of next month: // site/ready.php wire()->addHookAfter("RockFrontend::addLiveReload", function ($event) { // if the current user is a guest user we override the // original return value and set it to false // which will tell RF to not add livereload markup if(wire()->user->isGuest()) $event->return = false; });1 point
-
That shouldn't be a problem, actually. The WireHook class (someone correct me if I'm wrong) just builds a Selector and stores that in its hooks array. Every time a hookable method is called (through PHP's magic __call method), WireHook::runHooks is executed and checks wheter the any of the stored selectors match the currently called class and method and execute those. So it shouldn't matter when exactly you add the hook as long as PW's core has been loaded. For me, it's just a question of keeping the system startup lean why I perfer to add hooks in ready instead of init unless they have to be executed before ready() is triggered. In theory, it shouldn't matter, but I haven't delved too deeply into the issue.1 point
-
Version 0.2.2 of the ProcessWire IndieAuth Module is released: Admin tools to support the Client Credentials flow and manually adding a token when testing Added an Introspection endpoint Updated client information discovery. It now prefers the JSON document and falls back to parsing microformats2. Scoped dependencies so this can more easily run on the same site with ProcessWire Webmentions without conflicts More in the changelog1 point
-
No question, ProcessWire is fabulous for developers and the suggestions above would make it even better. Customers who are not developers are increasingly giving me feedback about how unintuitive the backend admin/editor is, especially now with the proliferation of DIY pagebuilders. Clients don't understand or care about the consequences. They care about not having to learn code to easily update their sites. They want the backend to look similar to the frontend, the convenience of doing it themselves without having to pay a developer. Too bad if the site doesn't work on all screen sizes, light/dark modes, isn't accessible, the home page looks like a ransom note, whatever. They genuinely don't like the default PW admin UI/UX. Pagegrid and RockPageBuilder modules are leading the way to solve this issue. Kudos to both developers BUT the modules are premium while a WP site gives customers basic WYSIWG page editing out of the box. My vote is to overhaul the admin UI/UX to make editing pages more WYSIWIG.1 point
-
That looks good! I have just finished a project with some complex layouts that required some nested RockPageBuilder blocks. And I did it the same way as you. I have multiple layouts block that just render the markup: A layout block looks like this: <?php namespace ProcessWire; use RockPageBuilderBlock\LayoutA; /** @var Page $page */ /** @var LayoutA $block */ ?> <section class="rpb-layouta" <?= alfred($block,["trash" => false, "clone" => false, "widgetable" => false])?>> <div id="div1" class="col-2x1"><?= $block->rpb_cell_2_1_a->render(true); ?></div> <div id="div2" class="col-1x1"><?= $block->rpb_cell_1_1_a->render(true); ?></div> <div id="div3" class="col-1x1"><?= $block->rpb_cell_1_1_b->render(true); ?></div> <div id="div4" class="col-2x2"><?= $block->rpb_cell_2_2_a->render(true); ?></div> </section> Inside there are some nested - custom - RockPageBuilder fields. Inside these fields you can insert various other RockPageBuilder content blocks. Like Text, Images, whatever. This is especially neat when editing the site in the frontend. The "naked" layout block looks like this: Then you can insert content to each of those cells via the nested RPB fields; However I have to say that the backend editing of these blocks is a bit "convoluted". When the project reaches a "final state" I will explain the details in a showcase here in the forum in more detail.1 point
-
That's great, thanks @Robin S! Works perfectly. A bit stupid of me - looking back at my old code I did use hasField, but evidently changed it during some other troubleshooting and didn't realise/forgot to change it back ?. As usual, the problem was entirely mine, and when in doubt, read the instructions!!1 point
-
I recommend uninstalling it as it has more problems than features. See : https://processwire.com/talk/topic/23457-functionality-clash-with-system-notifications/#comment-2154151 point
-
Understood. Thank you!1 point
-
This gets the inputfield name, not the field name. The inputfield name will have a suffix when it appears inside a repeater, so checking it against a particular field name is not a reliable way to identify the field. The settings for a Page Reference field gives you an example hook for when you want to use the "Custom PHP code" option. The example shows that the best way to identify the field is via the hasField property. So for your hook: $wire->addHookAfter('InputfieldPage::getSelectablePages', function (HookEvent $event) { $page = $event->arguments('page'); if($event->object->hasField == 'refStep') { // Your hook code here... } });1 point
-
Hi @SIERRA The problem isn't related to putting the content inside Processwire templates folders or how you implemented the paidhai template. The paidhai template requires 417kb only for the CSS (plus 100kb of not used javascript) when loading the website. That's a lot. The solution is to deliver only what is required (css, images, scripts) and defer everything else. To understand what is really required on the first load you can use the coverage tool in Chromes dev tools: 1. Open the chrome dev tools (Shift + Ctrl + I) 2. Open the command menu (Shift + Ctrl + P) 3. Type coverage and select the show coverage tool Coverage can help you to understand which content was loaded but is not being used (aka: things that you can defer). As you can see in the picture, 567kb are being loaded, but only 67kb were needed to render the first content. I never used Bootstrap before, but in your case I will probably try to understand what CSS & JS content is really needed. - Does your website really require all the CSS files on first loading (popup, carousel modal-video, font-awesome)? - Can you defer or async the main.js and jquery.js files? or move them to the bottom of the <body>? - Can you bundle some Bootstrap files to decrease the number of requests? To solve it you can do what @AndZyk told you. Use Critical to extract, minify and inline the critical css, and then use preload to load all the other CSS files. Also, maybe Optimize can solve the issue for you.1 point
-
Okay, I had a board in front of my head.? <div class="uk-child-width-1-2@s" uk-grid> <div>{$block->rpb_left->render()}</div> <div>{$block->rpb_right->render()}</div> </div>1 point
-
While testing I tried your version, too @bernhard but getting this.. Unknown Selector operator: '[empty]' -- was your selector value properly escaped? field='1672', value='', selector: '1672' in block #1671 (rockpagebuilderblock-twocolumns) This syntax works: ☺️ {$pages->get("$block->rpb_left")->text()} Looking forward to the insights @Stefanowitsch might have.? Any idea on how to output all possible blocktypes (like text, image,..) clever for both columns?1 point
-
Hi @sebibu thx for the great feedback ? Technically you can achieve that by creating a new block called "layout". Then you create two new RPB fields, eg column_left and column_right. Then you can add blocks to those fields, for example add "headline", "text" and "image" blocks to the column_left field. Then you can go to column_right and click add new block and click reuse existing block for all of your blocks. For the frontend you have to create the markup of your layout in the "layout" block's template file (eg layout.latte or layout.view.php). The problem with such setups is that it get's more complicated and you are moving the sweet spot between easy of use and features more towards features at the cost of more complicated content editing. On the backend RPB will show a button for nested RPB fields to edit those fields in a modal (or panel I think). So editors have to save the base page first, then can edit nested content. On the frontend this should be less of an issue. You can try and report back what you find. Also @Stefanowitsch might have useful tips as he built a quite complex page using RockPageBuilder recently and I think he is going to share something soon?! ?1 point
-
This module provides Captcha functionality to ProcessWire. This specific captcha uses a puzzle that has to be solved by pulling the slider into the correct position. In contrast to other graphical captchas, this captcha also verifies the result on the server side. No jQuery is required. Only PHP and JavaScript. After module installation the source code in the page has to be modified as described in the following 3 examples. Example 1 This example shows, how to use the captcha with a form-submit and the captcha on the submit-button. Insert a onclick-listener in the button-tag: <button onclick="javascript:captcha('testform');return false;">Submit</button> Add the JavaScript: <script> function captcha(form) { slideCaptcha.onsuccess(function () { document.getElementById(form).submit(); slideCaptcha.hide(); slideCaptcha.refresh(); }); slideCaptcha.init(); slideCaptcha.show(); } </script> The form is not submitted by clicking on the button. Instead, the captcha is displayed. If the captcha has been solved correctly, the form is submitted. Check again on the server side, whether the captcha has really been solved: <?php session_start(); if ((isset($_POST['send'])) && ($_POST['send'] == '1')) { if ((isset($_SESSION['SlideCaptchaOk'])) && ($_SESSION['SlideCaptchaOk'] == 'ok')) { unset($_SESSION['SlideCaptchaOk']); echo '<p style="color:lime">Form submit received: Captcha solved</p>'; } else { echo '<p style="color:red">Form submit received: Captcha NOT solved.</p>'; } } ?> Example 2 This example shows, how to use the captcha with a form-submit and the captcha on a checkbox. Insert a onclick-listener in the checkbox-tag: <input id="id_checkbox" type="checkbox" required="required" onclick="javascript:captcha('id_checkbox');return false;" /> Add the JavaScript: <script> function captcha(checkbox) { slideCaptcha.init(); slideCaptcha.show(); slideCaptcha.onsuccess(function () { document.getElementById(checkbox).checked = true; slideCaptcha.hide(); slideCaptcha.refresh(); }); } </script> By using the required option inside the checkbox-tag, the form can only be submitted when the checkbox is checked. By clicking on the checkbox, the captcha is displayed. If the captcha has been solved correctly, the checkbox will be checked and the form can be submitted. Check again on the server side, as described in example 1, whether the captcha has really been solved. Example 3 This example shows, how to use the captcha with a hyperlink. Insert a onclick-listener in the hyperlink-tag. Also move the href link into the JavaScript-function: <a href="" onclick="javascript:captcha('Example3.php');return false;">DOWNLOAD</a> Add the JavaScript: <script> function captcha(file) { slideCaptcha.onsuccess(function () { window.location.href = file; slideCaptcha.hide(); slideCaptcha.refresh(); }); slideCaptcha.init(); slideCaptcha.show(); } </script> The captcha is displayed by clicking on the hyperlink. If the captcha has been solved correctly, the JavaScript will redirect to the specified location. Check again on the server side, whether the captcha has really been solved and deliver the content: <?php session_start(); if ((isset($_SESSION['SlideCaptchaOk'])) && ($_SESSION['SlideCaptchaOk'] == 'ok')) { unset($_SESSION['SlideCaptchaOk']); header('Content-Type: application/octet-stream'); header('Content-Disposition: attachment; filename="Example3.php"'); readfile('Example3.php'); die(); } ?> Module settings The settings for this module are located in the menu Modules=>Configure=>CaptchaSlide. Filename Filename which must not exist in the root directory and also not represents a page. The filename must be also changed in the captcha.js. The resolving URL receives the information from the client side JavaScript. Tolerance Specifies a tolerance in order to offer better user experience. A tolerance of 3 means +- 3 pixel tolerance (3 recommended). Logging Logs unsolved and solved Captcha attempts in the ProcessWire system logs. Pages The JavaScript and CSS for the Captcha will be included into the following pages. Photos All photos provided by unsplash.com. As described on their website, all photos, offered on their website, can be used for free for commercial and non-commercial purposes: Link to module directory: https://processwire.com/modules/captcha-slide/ Link to github.com: https://github.com/techcnet/CaptchaSlide1 point
-
Multiple sites per account (Cloud version) Hi, I have just launched the new version of PAGEGRID Cloud (SaaS). It's now possible to have more than one site. I also removed some of the old restrictions for the free version. Now you can have unlimited sites, pages and items and only the webspace and publishing options are limited by the tier. This makes it more flexible and easier to get started. Simultaneously publish a portfolio, client website, idea boards, a profile site — basically any kind of site you need — all with a single account. Create as many sites as you like for free. Choose a desired service option and make a site public when you are ready to launch. Start with a blank canvas or use one of the site templates. Optionally buy a self-hosting license and export a site at anytime. (Of cause you can still host ProcessWire yourself and just install the PAGEGRID module from the modules directory.) Start for free (More templates will be added soon)1 point
-
My unsolicited opinion regarding a media manager: what I like about images / files being tied to a specific page is that it avoids creating clutter since the files are deleted when they're not needed anymore (the page is deleted) whereas if it was in a media manager you would probably end up with a lot of garbage. But I second the idea of maybe having something like @Robin S’ https://processwire.com/modules/process-media-lister/ to select an image from another page that would then be automatically duplicated on save.1 point
-
Anything wrong with this? wire()->classLoader->addNamespace("MyModuleNamespace", __DIR__ . "/classes"); This will add an autoloader for all files in folder __DIR__ . '/classes' where all these files need to have the namespace "MyModuleNamespace". See https://github.com/baumrock/RockAdminTweaks/blob/a8b82fff339ecf403966d806db398d20286219cd/RockAdminTweaks.module.php#L28 for an example. As far as I know require_once is problematic in multi instance usage, because you have different paths for the same class and that causes "fatal error: cannot redeclare class XYZ ..."1 point
-
I'd like to second this. It would be great if the new/improved admin theme was built with maximum customisability in mind. One use case is so that we can more easily offer a "mostly-frontend" user an admin experience that's radically different to what a superuser or site administrator gets in the uncustomised admin. Another admin customisation issue I've struck recently is when you want to customise markup for InputfieldWrapper. There's InputfieldWrapper::setMarkup() but this is marked as internal and isn't that practical to use because InputfieldWrapper::markup is static. That means any custom markup you set there persists for all InputfieldWrappers that are subsequently rendered, when what I want to do is customise markup for a specific instance of InputfieldWrapper. Edit: pull request When the admin theme is revisited it would be great to ask of each component that's rendered, "Is there an opportunity to make this rendering customisable?"1 point
-
Making ProcessWire stronger for full-stack web application development, allowing it to become an unassuming alternative to Laravel and Rails but from the origins as a CMS. ProcessWire is the perfect CMS (there's no doubt in my mind about that), and it's actually already quite good for web application development (both natively and with 3rd party modules), but with some enhancements to make it more "batteries included", enhancing page classes and some tooling, ProcessWire can have its feet in both the CMS and full-stack framework buckets in a way that's perhaps unique. I can elaborate on this further as that sounds a little too generic, but I've been developing a web application with PW for over 9 months (it's a very complicated project and it's replacing an existing, in-production system which makes it even more tricky and high-stakes) and when it's done I can share some ideas. This one enhancement alone moved the needle quite a bit in making ProcessWire more web application friendly.1 point
-
Did you set the autoload property in your module? I've assembled a snippet for site/ready.php that should add a checkbox to InputfieldSelector to allow system templates since the setting itself is already part of the inputfield code. Untested though since I'm in the middle of a big cleanup of my dev environment. wire()->addHookAfter('InputfieldSelector::getConfigInputfields', function (HookEvent $event) { $fields = $event->return; $inputfield = $event->object; $f = $event->modules->get('InputfieldCheckbox'); $f->attr('id+name', 'allowSystemTemplates'); $f->label = $event->_('Allow system templates'); $f->setAttribute('checked', $inputfield->getSetting('allowSystemTemplates') ? 'checked' : ''); $fields->append($f); $event->return = $fields; });1 point
-
1 point
-
DaCha is a water sports center in Egypt and a hotel. https://surfdacha.com/en/ Multi-language. The backend implements the management of customer reservations and bookings. Naturally, the website is made on ProcessWire. UiKit 3 layout Modules: LoginRegisterPro, Cookie Management Banner, Map Marker, FrontendForms, Markup Sitemap XML, Video embed for YouTube (and Vimeo), Tracy Debugger. The backend implements the management of customer reservations and bookings.1 point
-
The module provides a paths under which cronjobs can be registered. It lists all registered cronjobs and can execute individual ones manually. The last execution, the last status and, in the event of an error, the last error message are displayed. Download & Install Github: https://github.com/neuerituale/ProcessCronJobs Modules directory: https://processwire.com/modules/process-cron-jobs/ Composer: coming soon1 point
-
Repeaters are output as PageArray (or rather a class that inherits from it, called RepeaterPageArray), so you have all the methods from a WireArray such as: https://processwire.com/api/ref/wire-array/get/ https://processwire.com/api/ref/wire-array/find/ $page->repeater_field->get('FieldA=2')->FieldC1 point
-
Or just provide an ASM multi-select field with a list of the fields that the client can order as they desire. You could do this manually with an Options fieldtype, or perhaps with this: http://modules.processwire.com/modules/fieldtype-fields/ which lets you limit the listed fields based on a selector. You could add this field to a separate "Field Order" tab to keep things clean. Of course then you order the output of the fields in your template file based on the order they have selected.1 point
-
I think you are looking for something like this. You need to be making use of the names of the repeater fields and also referencing the repeater field relative to it's containing page. foreach($l->{$f->name} as $repeater_item) { foreach($repeater_item->fields as $rf) { echo $repeater_item->{$rf->name}; } }1 point