Leaderboard
Popular Content
Showing content with the highest reputation on 05/31/2024 in all areas
-
This week the core dev branch version remains at 3.0.239 but relative to last week, it contains several optimizations and improvements. Details can be found in the dev branch commit log. I've also moved two Textformatter modules out of ProFields and into GitHub and the modules directory. These include: Auto Links This Textformatter module automatically links your specified phrases/words to your specified URLs. This is a potential SEO and accessibility tool for creating automatic contextual links with little effort. If there are pages that you commonly link to in your site from your textarea/rich text fields, then this Textformatter can save you some effort, automatically linking to those URLs. Text Blocks This Textformatter module enables you to assign a name to any block/region of text in a Textarea field. They are defined by typing start_name where you want the block to start, and stop_name where you want the block to stop. The block(s) of text can then be shown in any other Textarea field at runtime (site-wide) simply by typing the block name on its own line in the format show_name. Note that the word "name" in all of these examples would be whatever you've decided to name the block. Both modules have been updated just for public release with a new version. Both are considered Stable, as they have both been running without incident for several years. These modules were moved from ProFields to the public modules directory for three reasons. First is that they don't consume hardly any support resources, so they don't need to be commercially supported modules anymore. Second is that I'd like to keep ProFields focused more on field related modules (Fieldtype, Inputfield, and related) rather than Textformatter modules. Though admittedly the TextBlocks module does blur the line a bit, as it promotes potential greater reusability with existing Textarea/TinyMCE/CKEditor fields. Third is that there's already a lot in ProFields and I wanted to make room for new modules, such as the recently added PageEditChildren, which is part of ProFields at least in the short term. The FunctionalFields module may come out of ProFields well, as it hasn't required much in terms of support resources recently, though it is a useful Fieldtype/Inputfield module that is very much in keeping with the theme of ProFields, so I'm still debating on that one. Thanks for reading and have a great weekend!11 points
-
Multi field support The latest version adds support for multiple PAGEGRID fields per page. This makes PAGEGRID more flexible when you want editors to control only some parts of the layout. Each field can use its own block templates: If you want to render more than one PAGEGRID field per page, you can call the render function for a specific field like this (assuming you added the fields named “mygrid” and “mygrid2” to your page template): <!-- render markup for field mygrid --> <?= $page->mygrid; ?> <!-- render markup for field mygrid2 --> <?= $page->mygrid2; ?> The old render function $pagegrid->renderGrid($page) still works, but it will always render the first field it finds. You can use $pagegrid->renderGrid($page, $field) or $page->fieldName to render a specific field. Custom code and markup You don’t have to write complicated foreach statements, PAGEGRID takes care of rendering clean markup. PAGEGRID wraps each item in a wrapper element. You can change the tag name or add custom classes to it easily. The rest of the markup is inside your block templates. Nice and clean. Add this function at the top of your block template file to change the wrapper element: <?php //The wrapper element of this block template uses the section tag and some custom classes $pagegrid->renderOptions(['page' => $page, 'tag' => 'section', 'classes' => 'my-class my-class-2 foo-class']); //Here goes your markup ?> CSS code It’s also easy to control the behavior of the grid using only CSS code (If you prefer to write your own CSS code or include a CSS framework, you can disable PAGEGRID‘s style panel): /* overwrite PAGEGRID defaults */ /* wrapper */ /* Use 6 equally sized grid columns */ .pg { grid-template-columns: repeat(6, 1fr); } /* items */ /* set both properties to auto */ /* let grid items take the available space */ .pg .pg-item { grid-row-start: auto; grid-column-start: auto; } /* or set only grid-row-start to auto */ /* items can still be positioned freely on the columns */ .pg .pg-item { grid-row-start: auto; } /* new items */ /* you can use this class to set the defaults for new items */ /* here we are overwriting the default size of grid items */ /* using this class makes sure you can still resize items with the PAGEGRID field */ .pg .pg-item-added { grid-column-end: span 3; /* let new grid items span 3 columns */ grid-row-start: auto; /* you can also change the placement here */ } You don't even have to use grid, flexbox or block also works. PAGEGRID makes no assumptions about your CSS code. Just make sure to call your stylesheet after you render the styles from PAGEGRID, so you can overwrite the defaults. Item Placement As a default dragged items will be placed manually on the grid. Manually placed items can overlap themselves. Here is a quick example, how the CSS properties grid-row-start: auto; and grid-column-start: auto; effect the dragging of grid items: Backend/Frontend PAGEGRID renders the same template in the backend (iframe) and frontend so the design will look the same. If you want to render only some parts in the backend you can use this check: <?php if( $pagegrid->isBackend() ) { // render things only for the backend } else { // render things only for the frontend } ?> Alternatively you can also load different templates for the backend and the frontend. E.g. you can do this at the top of your template file (assuming you use your own template file instead of the default pagegrid-page.php): <?php namespace ProcessWire; // in the backend we render the default template and return (renders just the field) // ignores markup regions by default (file has $pagegrid->noAppendFile($page)) and just renders that file if( $pagegrid->isBackend() ) { include('pagegrid-page.php'); return; } ?> <!-- render frontend stuff here (you can use markup regions if you like ) --> <div id="content"> <p>Custom frontend code for <?= $page->title ?></p> <!-- render PAGEGRID for the frontend --> <?= $pagegrid->styles($page); ?> <?= $pagegrid->renderGrid($page); ?> <?= $pagegrid->scripts($page); ?> </div> In this case you have to load your custom CSS code in both files if you want the backend/frontend to look the same. For more examples check out the docs6 points
-
If the developer of your website hasn't implemented such a feature, you won't be able to find it. ProcessWire will only let you do things that the developer thought were a good idea. And many developers will probably think that letting the client insert untrusted code is not a good idea... You'll find the code of the website on the server. Usually you can connect via FTP or some hosting providers have web based file management tools. From there it should be quite easy to find the file to put the code into. Usually it will be in the /site/templates folder. If you have a _main.php file there this will most likely hold the main markup of your website that all pages use. If not you can open /site/templates/home.php or /site/templates/basic-page.php and inspect the code there. If those files all have something like <?= include('sections/footer.php') ?> you'd put your markup in one of the included files that get's included by all templates.5 points
-
Hey ProcessWire friends! @protro asked something about Strapi in another thread, so I did a quick research on how to build a basic frontend for content stored in Strapi and found this 20+ video on youtube: Now, don't get me wrong, Strapi is cool and all and the video is really great, but I couldn't help but chuckle thinking about how we do basically the same in ProcessWire. Here's our "epic" version: <?php foreach($pages->find('template=faq') as $faq) { echo "<div><h2>{$faq->question}</h2>{$faq->answer}</div>"; } Boom! Done in a few lines. No need for popcorn or a comfy chair. ? Cheers to simplicity and efficiency! ? #ProcessWireFTW #KeepItSimple #LessIsMore4 points
-
Reactions is a module that collects reactions for pages from site users/visitors based on a click of a reaction button. It's basically the same thing as those "did you find the information you were looking for" thingies you see on some sites. An example of what the buttons might look like: There is also a very simple process module that displays pages along with their reaction counts for each enabled reaction type. GitHub repository: https://github.com/teppokoivula/reactions Modules directory: https://processwire.com/modules/reactions/ Needed this for a project and was kind of in a hurry, so it's not super polished, but seems to work well for basic use cases. One thing that's kind of fun (or scary) about this module is that it modifies the structure of the reactions database table automatically based on active buttons; this is done using ProcessWire's built-in features ? Getting started You can install the module the usual way; clone or download the code, or install via admin. Or via Composer: composer require teppokoivula/reactions The easiest way to define available buttons is via site config: $config->reactions = [ 'reaction_types' => [ 'like' => [ 'title' => 'Like it', 'icon' => '<svg xmlns="http://www.w3.org/2000/svg" height="24" viewBox="0 -960 960 960" width="24"><path d="M720-120H280v-520l280-280 50 50q7 7 11.5 19t4.5 23v14l-44 174h258q32 0 56 24t24 56v80q0 7-2 15t-4 15L794-168q-9 20-30 34t-44 14Zm-360-80h360l120-280v-80H480l54-220-174 174v406Zm0-406v406-406Zm-80-34v80H160v360h120v80H80v-520h200Z"/></svg>', // optional attributes, either as an associative array or as a string, e.g.: // 'attrs' => [ // 'data-some-attr' => 'value', // ], // 'attrs' => 'data-attr="value"', ], 'love' => [ 'title' => 'Love it', 'icon' => '<svg xmlns="http://www.w3.org/2000/svg" height="24" viewBox="0 -960 960 960" width="24"><path d="m480-120-58-52q-101-91-167-157T150-447.5Q111-500 95.5-544T80-634q0-94 63-157t157-63q52 0 99 22t81 62q34-40 81-62t99-22q94 0 157 63t63 157q0 46-15.5 90T810-447.5Q771-395 705-329T538-172l-58 52Zm0-108q96-86 158-147.5t98-107q36-45.5 50-81t14-70.5q0-60-40-100t-100-40q-47 0-87 26.5T518-680h-76q-15-41-55-67.5T300-774q-60 0-100 40t-40 100q0 35 14 70.5t50 81q36 45.5 98 107T480-228Zm0-273Z"/></svg>', ], 'haha' => [ 'title' => 'Haha!', 'icon' => '<svg xmlns="http://www.w3.org/2000/svg" height="24" viewBox="0 -960 960 960" width="24"><path d="M480-260q68 0 123.5-38.5T684-400H276q25 63 80.5 101.5T480-260ZM312-520l44-42 42 42 42-42-84-86-86 86 42 42Zm250 0 42-42 44 42 42-42-86-86-84 86 42 42ZM480-80q-83 0-156-31.5T197-197q-54-54-85.5-127T80-480q0-83 31.5-156T197-763q54-54 127-85.5T480-880q83 0 156 31.5T763-763q54 54 85.5 127T880-480q0 83-31.5 156T763-197q-54 54-127 85.5T480-80Zm0-400Zm0 320q134 0 227-93t93-227q0-134-93-227t-227-93q-134 0-227 93t-93 227q0 134 93 227t227 93Z"/></svg>', ], ], ]; ... though you could also add them programmatically, e.g. if you wanted to manage them via admin: $wire->addHookBefore('Reactions::setReactionTypes', function(HookEvent $event) { $reaction_buttons = $event->wire()->pages->get(1)->reaction_buttons; if ($reaction_buttons->count()) { $reaction_types = []; foreach ($reaction_buttons as $reaction_button) { if (!$reaction_button->title) continue; $reaction_types[$reaction_button->name] = [ 'title' => $reaction_button->title, 'icon' => $reaction_button->icon && $reaction_button->icon instanceof Pageimage ? $reaction_button->icon->filename : null, ]; } if (!empty($reaction_types)) { $event->arguments(0, $reaction_types); } } }); The module has basic styles and scripts bundled in, though you'll have to load them yourself: <link rel="stylesheet" href="<?= $config->urls->Reactions ?>styles/reaction-buttons.css"> <script src="<?= $config->urls->Reactions ?>scripts/reaction-buttons.js"></script> ... and then call the render method to render the buttons in your template file(s): <?= $modules->get('Reactions')->renderReactionButtons() ?> For those interested in doing stuff like displaying something based on the answer, bundled JS triggers an event that you can listen to: document.dispatchEvent(new CustomEvent('reactions-updated', { detail: { pageID: pageID, reaction: reaction, }, }, { bubbles: true }));3 points
-
If you prefer one-liners: <?php // https://processwire.com/api/ref/wire-array/each/ echo $pages->find('template=faq')->each("<div><h2>{question}</h2>{answer}</div>\n"); ?3 points
-
2 points
-
I have made several websites with this kind of structure: home projects project1 project2 project3 In my cases, the home page lists all projects, so the home/projects/ page is a double of home’s function. What would be the best practice? create a list of projects specially for projects/ even if it does the same as home/ redirect projects/ to home/ (I found ProcessRedirects can’t do that as the page is already exists, but maybe I can force it with .htaccess?) something else? Thank you for your advice.1 point
-
Hi, With the introduction of GDPR regulations, many of our clients with "webuser" systems we've developed need a way to email users that haven't logged-in in a while (18 months seems to be the standard) to ask them if they still want their user account. For most of the systems we've developed, we've added a field to the user template which records the time when the user logs in, so we'll be able to develop this functionality. It got me thinking, would this be a welcome addition to the core, accessed in a similar way to created/modified dates e.g. $user->lastlogin? Were it to be implemented, it would be useful to be able to 'silently login' if using $session->login($username, $pass) or $session->forceLogin($username), in the same way you can bypass save hooks by passing in an option to $pages->save(). Cheers, Chris - NB Communication1 point
-
@flydev Oh sorry, I got it now. ??♂️ I followed the Readme without thinking. To call the module on all templates I have added it to the _init.php. Now it is working as expected. Ryans Prod module looks like a good alternative. For now, I do prefer the Blackhole module. It is lightweight, quick and easy to implement.1 point
-
Didn't you feel like you were reading a comic book, because it looked so easy and the code is so well written/commented? Ryan is so skilled you quickly realize that the tool is robust lol Just played with a chatbot that will be soon publicly available (need to ask ryan and mods) with some @MarkE text chunk from this thread :1 point
-
1 point
-
As the error message says, check site/templates/_uikit.php on line 830. This file calls for data you've removed, therefore the error.1 point
-
There are also the new URL/path hooks: https://processwire.com/blog/posts/pw-3.0.173/1 point
-
Hey @netcarver and @gebeer great news for you (and all RockFrontend users) I've fixed an issue with ajax endpoints not replacing ALFRED markup (thx for the report @gebeer) and while working on that I got quite a lot of errors in the console about the livereload stream having a wrong mimetype, which has also been observed and reported by @netcarver some time ago. So I fixed that as well ? Please try the latest version on the dev branch, which will be merged to master in some days. LiveReload only reloads the visible tab. This is to avoid endless loops where one window reload causes the other one to reload as well and vice versa. In older versions you had to reload the tab manually once you switched back to it. In the latest version it will wait and as soon as you switch back to the tab it will be reloaded automatically if a file changed in the meantime ?1 point
-
@flydev I stumbled upon this wonderful module. Thank you so much! I have noticed that version Blackhole 1.1.0 does not block the entire site as stated. Once the IP address has been blocked, it is still possible to load any sub pages. It only blocks access to the front and blockhole page. I have tested it with a clean PW 3.0.229 install. Can you reproduce it?1 point
-
@nurkka - I agree, but a couple of things that might help you in the meantime. If you install https://processwire.com/modules/module-settings-import-export/ it will automatically backup module settings when it's uninstalled so that you can easily get settings back where they were when you reinstall it. Also, Tracy's Module Disabler panel can be helpful to disable modules without uninstalling - the catch is that it needs advanced and debug modes turned on to work.1 point
-
@ryan - I wonder if PW might automatically include those gc tweaks when Debian is detected? Maybe via something like this. Perhaps it could be run at install, rather than runtime if you're concerned about performance although it is only about 1ms. if (strtolower(substr(PHP_OS, 0, 5)) === 'linux') { $vars = array(); $files = glob('/etc/*-release'); foreach ($files as $file) { $lines = array_filter(array_map(function($line) { // split value from key $parts = explode('=', $line); // makes sure that "useless" lines are ignored (together with array_filter) if (count($parts) !== 2) return false; // remove quotes and new lines $parts[1] = str_replace(array('"', "'", "\n"), '', $parts[1]); return $parts; }, file($file))); foreach ($lines as $line) { $vars[$line[0]] = $line[1]; } } d($vars['ID']); }1 point
-
Edit: Solution is at the end of this comment, after a few educational dead ends. ? @gebeerI use EasyApache4; just standardized automated upgrade/changes on a VPS with a few PW websites that have been running fine for years. I have not improvised anything, not made any manual configuration changes. Of course there is a misconfiguration somewhere. I'm trying to find out where and created this thread to find out if anyone had seen something similar after PHP config changes. Here's one via a Google search - also uses CentOS, but with Apache vs Nginx issue, so problably not relevant. Thanks for the file permissions link. I'll see if I can fix my problem with that, but they're not clearcut instructions what ownership and permissions each folder/file should have. I see my Apache now runs as 'nobody'; I think it used to be/should be 'myusername'? My PW sites were installed as 'myusername' and all folders/files are owned by that 'myusername'. Edit: EasyApache apparently "updates" user settings or PHP handlers (?) and you have to turn that off? Here is a possible way to make Apache run as 'username' instead of 'nobody', I think, from 2012, so not risking that one... WHM has Apache mod_userdir Tweak where only 'DefaultHost (nobody)' has 'Exclude Protection' selected and all my other hosts/website have 'myusername'. No clue what to do with that info. Can I change DefaultHost to 'myusername' anywhere? There's this file on my CentOS server: # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! # DO NOT EDIT. AUTOMATICALLY GENERATED. USE INCLUDE FILES IF YOU NEED TO MAKE A CHANGE # !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! # # Direct modifications to the Apache configuration file WILL be lost upon subsequent # regeneration of this configuration file, or an Apache update. # # To have your modifications retained, you should create/edit administrator-specific # include files: # # /etc/apache2/conf.d/includes/pre_main_global.conf # /etc/apache2/conf.d/includes/pre_virtualhost_global.conf # /etc/apache2/conf.d/includes/post_virtualhost_global.conf ... # These are hard-coded values that are required by cPanel & WHM PidFile /run/apache2/httpd.pid User nobody Group nobody ... Tried changing 'nobody' to 'myusername' in pre_main_global.conf, empty file with only this: User myusername Group myusername And then run these two commands from root in SSH to rebuild httpd.conf and restart Apache: /usr/local/cpanel/scripts/rebuildhttpdconf /usr/local/cpanel/scripts/restartsrv_httpd One site that was giving me nasty 500 server errors is suddenly back, but that could also be because I changed permissions on all folders to 777 - bad for security... <?php echo exec('whoami'); ?> is still giving me 'nobody' as Apache user. Apache mod_userdir Tweak in WHM still has 'DefaultHost (nobody)'. Another clue here: 'If you install the suEXEC module, the system executes PHP applications as the user that owns the VirtualHost that served the request. If you uninstall the suEXEC module, the system executes PHP applications as the nobody system user.' mod_suexec is an Apache Module that can be enabled in EasyApache4. Enabling that seems to fix most issues I had. <?php echo exec('whoami'); ?> now give the correct 'myusername'. Edit: There is also another Apache Module mod_suphp that may be required to fix issues with some scripts.1 point
-
You should be able to set permanent=false in your module info, and then in your admin do a Modules > Refresh. But if that doesn't do it, you could always update the 'flags' column for that module to be 0 (in the modules table), and then after a Modules > Refresh it should definitely let you uninstall/remove it.1 point