Leaderboard
Popular Content
Showing content with the highest reputation on 06/28/2021 in all areas
-
Process Images A basic, proof-of-concept Textformatter module for ProcessWire. When the Textformatter is applied to a rich text field it uses Simple HTML DOM to find <img> tags in the field value and passes each img node through a hookable TextformatterProcessImages::processImg() method. This is a very simple module that doesn't have any configurable settings and doesn't do anything to the field value unless you hook the TextformatterProcessImages::processImg() method. Hook example When added to /site/ready.php the hook below will replace any Pageimages in a rich text field with a 250px square variation and wrap the <img> tag in a link to the original full-size image. For help with Simple HTML DOM refer to its documentation. $wire->addHookAfter('TextformatterProcessImages::processImg', function(HookEvent $event) { // The Simple HTML DOM node for the <img> tag /** @var \simple_html_dom_node $img */ $img = $event->arguments(0); // The Pageimage in the <img> src, if any (will be null for external images) /** @var Pageimage $pageimage */ $pageimage = $event->arguments(1); // The Page object in case you need it /** @var Page $page */ $page = $event->arguments(2); // The Field object in case you need it /** @var Field $field */ $field = $event->arguments(3); // Only for images that have a src corresponding to a PW Pageimage if($pageimage) { // Set the src to a 250x250 variation $img->src = $pageimage->size(250,250)->url; // Wrap the img in a lightbox link to the original $img->outertext = "<a class='lightboxclass' href='{$pageimage->url}'>{$img->outertext}</a>"; } }); GitHub: https://github.com/Toutouwai/TextformatterProcessImages Modules directory: https://processwire.com/modules/textformatter-process-images/9 points
-
A companion Module for RockMigrations to gather and execute Migrations in one place. !Alpha RELEASE! Hi there, I just wanted to share my take on Migrations and how I am using RockMigrations to make my deployments somehow manageable. First of all, a big shoutout to @bernhard for his efforts and accomplishments for our beloved CMS. We recently had a video-call and talked about our daily problems and how to handle them, with a focus on Migrations. As of now you might think 'Gosh, not another Migrationsthingy' but wait. Wouldnt it be nice to have a nice overview or some kind of list regarding Migrations and stuff and one place to manage them? Speaking for my own, yes I would like to have something like this. So yeah, here we are with a Companion Module for RockMigrations. Product Requirements I want to manage Migrations on the Application level (done) I want to have one place in my FileSystem to place my Migrations (done) I want to see in which state my Migrations are (done) I want to have an execution order, execute migrations one by one (done) I want to trigger Migrations via CLI (open) I want to group multiple Migrations into One Migration to create Build Versions (open) I want to Rollback Migrations (open) I want to create a deliverable build out of migrations (open) I want to track changes to templates and fields and create migrations accordingly (open) I want to manage Migrations on the Module level (open) Module Requirements ProcessWire 3.0.178 RockMigrations latest PHP 7.4 Composer Current release: v1.0.2Alpha How does it work? On installation the Module will create a new Database Table, here we will hold information about migrations states. Your Migrations are empty on first installation, so just click on You can now choose which Type of Migration you want to create, be it Templates, Fields or Pages and a according Action. Im still working on this function, so yeah its a lil bit confusing right now. The philosophy here is, every Type of Migration could be easily identified and we can Migrate on a very sepcific and granular base. As you can see in my Screenshot, I am using migrations to build an entire App from Migrations. After creating the new Migration File, switch over to your IDE and find a timestamped .php file inside modules/FlowtiCore/migrations. This file just returns a simple Array. This is all the Info RockMigrations needs to do his thing while we keep track of the execution. Easy. Values Arrays have to follow PW and RockMigration field naming Conventions. To make a Migration Executable set 'boilerplate' to false. After creation of your first Migrations your overview should be filled so lets go. We have to migrate our files in a specific order just to make sure we can create page_references and Parent/Child connections. To achieve this, Migrations are timestamped on creation. The older the higher the priority. To enforce execution order, every migration needs to have his predecessor executed and installed. How could this help my workflow? My workflow is based on Git, Webhooks and Git Events. So whenever I merge 'staging' into 'master', a build will be created and a deliverable should be pushed to a Server via SSH. The Problem with ProcessWire is the lack of support for such Workflows and Toolchains due to its User-Friendly Admin Backend which is fine for a simple website but not suitable long-term if working in a multi-tenant environment or with more developers in a dev-staging-test-production setup. My Goal is to provide methods and ideas to support such workflows but also support a User-Friendly Interface to work with migrations. I really hope it could be of use for someone. Installation I will add the Module to the Directoy once it reached a stable state. But you can get current version at GitHub https://github.com/Luis85/FlowtiCore Just clone it to your Modules Directory. The Module will create a new Database-Table on creation. The Default Name will be 'flowti_core_migrations'. To change this just edit const DATABASE_TABLE = 'flowti_core_migrations'; Inside the Module Class. Thats it, from there on just create new Migration Files, edit them and execute them.3 points
-
A few days ago I stumbled upon this old module, which had been laying in the modules directory of one of my sites since 2017 in a half-finished state. I have no recollection why I left it like that, but figured it might be useful for someone, so here we go: https://github.com/teppokoivula/Snippets https://processwire.com/modules/snippets/ Snippets is a tool for injecting front-end code snippets (HTML/JS/CSS) into page content. The way it works is that you create a snippet — say, a Google Analytics tag — and then choose... which element it should be tied to (there are some pre-populated choices and custom regex option), whether it should be placed before/after said element or replace it entirely, and which pages the snippet should apply to. The "apply to" option also has some ready to use options (such as "all pages" and "all non-admin pages") or you can select specific pages... or use a selector. Snippets are regular markup, with the exception that you can use values from current page (behind the scenes the module makes use of wirePopulateStringTags()). Available hooks: Snippets::isApplicable, which receives the snippet object and current Page object as arguments and returns a boolean (true/false). Snippets::applySnippet, which receives the snippet object, page content (string), variables (an object derived from WireData), and an array of options for wirePopulateStringTags() as arguments and returns the modified page content string. That's just about it. It's a pretty simple module, but perhaps someone will find this useful ?2 points
-
Here is a simple proof-of-concept Textformatter that might help: You can adapt the example in the readme to add a lightbox link to your images.2 points
-
I've got some core updates in progress but nothing major committed yet, so we'll save that for next week. But I wanted to briefly tell you about a module I'm working on here, which I plan to eventually put in core. I built it for some needs I've had here, but it will first be released in ProDrafts (so ProDrafts may start using its API), and in ProDevTools too, since it is also a developer tool. It's a snapshot versioning system for pages, but more of an API tool at this stage, kind of like the $pages API var, but for snapshots/versions of pages. It lets you create a snapshot of any page, including its fields and files (including core fields, ProFields, 3rd party fields, repeaters, nested repeaters, table fields with a million rows, etc.). The snapshots can be restored at any later time. Snapshots may also be restored to a different page, such as a new or existing page. In this manner, a module like ProDrafts may be able to use it to manage draft versions even better than it currently can, or at least that's the plan. Though since it's an API tool, my hope is that when/if it winds up in the core, others may be able to use it for stuff we've not thought of yet too. The module is a little different than my previous attempts (like what's in ProDrafts now) in that it does most of its work directly at the database level (and file system level, where applicable), which enables it work without needing to know much about the Fieldtype. Currently it is fully functional, but I have a few less common cases to work out before it's ready for release. Once installed, every page includes a Snapshots fieldset, which can be located in the settings tab of the page editor, or a separate tab in the page editor (configurable). When installed, every page has one, so long as the user has the appropriate permissions. There's a screenshot of what it looks like in the page editor below, but it is very simple at this stage, basically just enough for testing purposes. Every snapshot has a name that is unique on the page. You can overwrite a snapshot just by saving a snapshot with the same name on the same page. So you could for instance have a hook that creates a snapshot named "undo" right before a page is saved (in a Pages::saveReady hook), and in that way a module could add a basic undo capability to the page editor. This is just a simple example though. Thanks for reading, have a great weekend!1 point
-
To be honest... what you @LuisM and @bernhard built... it's somehow awesome but either way somehow insane. I love it... even though I almost will never use it by myself... as it's either too complex or way out of my comfort zone. (for now) Yet... I really appreciate what you @bernhard do for the community with all your modules and ideas and you @LuisM who builds things on top of it. Love it!1 point
-
I just released the latest version with some fixes from @bernhard. Thanks for the corrections. I also updated the dev branch with latest translations to the core 3.0.180. Enjoy1 point
-
1 point
-
This seems like an issue with ProcessWire itself, not SearchEngine. If you have a chance you might want to give the latest dev version of ProcessWire a try, though if it's a live site then I'd recommend doing it locally / in a development environment first, or alternatively backing your site up before the update (just in case). If that doesn't solve it, you may want to open an issue for this at https://github.com/processwire/processwire-issues. "Internal Server error" alone isn't very informative, so you may also want to dig into your log files etc. to see if there's anything more specific there.1 point
-
Settings Factory was created precisely for this use case - no need to create a module, module config; You can also keep your fields in your module with default values, and let your site admins override those in the Settings Factory "settings". To put it simply, if you are building out module-like code on the front end, but need to expose settings for things to your editors, Settings Factory has the ability to create unlimited settings pages, each with their own permissions...1 point
-
depends on what you are doing – if you mean that you can't access the api vars inside a function, that's one issue; usually i put all of the helper functions inside /site/templates/helpers/ and then include them in the template folder _init.php file and that definitely works. If you need to use those in the admin then that's also a different thing, but in short you should be able to do some quick tests like write a simple function in the ready.php file and see how it works.. then move it to your include file and see if it still works...1 point
-
This sounds fantastic. A couple of our clients have been wishing for something like this and have tried using the clone/copy feature to try to achieve it, but then have issues such as the CkEditor fields pointing to the wrong page's files. Would this feature resolve that issue?1 point
-
You could edit /site/templates/admin.php so that it looks something like this: // Get the user's IP address $ip = $session->getIP(); // Define the allowed IP addresses $allowed_ips = ['111.111.111.111', '222.222.222.222']; // Check user's IP is allowed if(!in_array($ip, $allowed_ips)) { return 'Access denied'; } require($config->paths->adminTemplates . 'controller.php');1 point
-
More fun (can't upload animated gif) with style switcher... style-switcher.mp41 point
-
Following the above discussion, I decided that it made more sense to display the title rather than the path (since it is only for display purposes). I also wanted a solution for attribute types pagelistselectmultiple, not just pagelistselect. In case it is useful to anyone else, my suggested js is: $(document).ready(function() { /* Author: Mark Evens, based on an original script by Robin Sallis */ /* This version displays the title text rather than the path name */ /* It also works for pagelistselectmultiple as well as pagelistselect */ /* Hide the text field */ /* id_title is the name of a text attribute in the hanna code*/ /* change id_title throughout the code below to match your attribute name */ $('#wrap_id_title').addClass('hide-field'); // Must use mousedown instead of click event due to frustrating event propagation issues across PW core // https://github.com/processwire/processwire-issues/issues/1028 // .PageListActionSelect is the button 'Select' with appears when a page is clicked (no normally visible - loaded by js) $(document).on('mousedown', '.PageListActionSelect a', function (event) { var id_title; // Adapt unselect label to suit your language if ($(this).text() === 'Unselect') { id_title = ''; } else { id_title = ($(this).closest('.PageListItem').children('.PageListPage').text()); // replace .text() by .attr('title') for path name } $('#id_title').val(id_title); }); // For pagelistselectmultiple, get all the selected pages when the selection is updated // This returns the contents of the label displayed in the pagelist item. This can be set in your HannaCodeDialog::buildForm hook // The default is the page title. For the path name, set $f->labelFieldName = 'path'; in your hook $(document).on('change', '.InputfieldPageListSelectMultiple', function(event) { var id_title = []; $(this).find('.InputfieldContent ol li:not(.itemTemplate)').each(function(){ id_title.push($(this).children('span.itemLabel').text()) }) $('#id_title').val(id_title); }); }); To hide the id_title attribute in the dialog, you need to add the following css: #hanna-form .hide-field { display: none !important; }1 point