Leaderboard
Popular Content
Showing content with the highest reputation on 03/31/2025 in all areas
-
Hey all! I've been creating new block/widget buttons for the current project I'm working on and wanted to share them in case they may be useful to others. They're SVGs intended to complement the style of buttons that come with RockPageBuilder. This post has been updated with a link to a Github repository containing all of the buttons currently available. New buttons have been added. Existing buttons have have been tweaked for quality and consistency. Download from or fork the Builder Buttons Github repository Rather than keep this post up to date with every button that is added, visit the Github repo to see the most current example and download/clone buttons for use in your projects. Buttons include: Accordion Announcement Articles Audio Bios Call To Action Card Over Image Code/Embed Events Image Image Carousel Image Mosaic Image Roll List Lists Products Reviews Video Weather Preview (not in order of list) If you find them useful, let me know what you think!2 points
-
@bernhard I wasn't able to provide a more robust response above but I wanted to mention that my concept wasn't an impulsive decision. I think my language in the confirmation popup should be changed. The "clear all" feature is a shortcut to clear all content in all languages including the default language so that it has one purpose. One of the things that I first had to consider was how often the feature gets used. Fluency has been available for over 5 years and this feature absolutely has great value but hasn't been mentioned before. I haven't heard about users/devs expressing a need to clear all content from multilanguage fields, and the general practice has been in my experience that if content changes then it would involve entering new content and re-translating. I thought about weighing how often the feature would be used compared to translation and it seemed like much less often, but I didn't have experience to go on. I also wondered if this was a feature that was use most during the initial build and population of content vs. ongoing content management. I think that was another area where the use of the feature may change over time as far as how often it's used, but again I haven't had the need so my understanding may be limited there. I'm not against the concept of a always-visible button or icon. Throughout the admin UI the trash icon is, as far as I can tell, mainly implemented for block, group, or object deletion rather than field contents. This is where the use of the trash icon without a label to explain the difference between what it means when used specifically for a field could be confusing because it does break from what it signifies elsewhere. The position of the translation action menu to the right as a clickable option felt natural with destructive actions located elsewhere. Placing it under a dedicated language icon menu seemed like it would strongly associate the action exclusively with multilanguage field features. Each field can have translation disabled, so there would have to be a decision whether to include just a trash icon even if there is no translation enabled for consistency when working with multilanguage fields. I think this could be a great convenience enhancement even if it steps outside of Fluency's current purpose and may be even be necessary for consistency. This may present another challenge because only multilanguage fields would provide the ability to delete content from the primary field that is visible where all other fields that only have primary content would need to manually be deleted. It's a step that may push a little further into ProcessWire's core behavior because some fields enable you to delete content for the default language alone, but other fields that are not multi-lingual still require a select-all-then-delete action by the user. If the trash icon is not present on all fields, would it seem like an oversight? Another thing that comes to mind is whether a multilanguage field with translation disabled were next to a single language field. On the left you can delete the primary content without deleting any other language, but on the right you can't delete the primary content with one click. The tabs hint that it's related to language fields, but non-language fields aren't afforded the same convenience even though they are visually similar to the end user. The intention is to have the clear all button clear everything in one action, so if the user is aware of the feature then they wouldn't clear any text to begin with. I think the language I used in my original "confirm" example may not have been as descriptive as it should be. It's an all-or-nothing action. The wording you used: "Are you sure you want to clear content in all languages for this field?" is much better and communicates clearly. So my approach was placing the option under an action menu since it felt natural to group secondary behaviors. The button that opens the translator is secondary and the ability to delete content in all languages is secondary compared to the primary feature of translation. I like the ideas and want to take the best approach, and I'm not against any specific implementation. Thinking through this though when you originally mentioned stepping into "core" behavior may be more impactful than it seemed when putting all different types of fields into the mix.2 points
-
Reviving this for a slightly different use case. I need to serve a different templates folder based on a certain URL segment. My code goes in site/config.php. In there $input is not available yet. So the logic uses $_SERVER['REQUEST_URI'] /** * Switch ProcessWire templates directory based on the second URL segment. * Type the second URL segment as key and the name of the new templates folder as value. * Example: '/imaging/' maps to 'templates-magazine' folder. * We use the second segment because the first segment is always the language (en, de, etc.) */ $config->templateSegments = array( 'imaging' => 'templates-magazine', // first url segment => templates folder name // Add other segment => folder mappings here ); // Check the second URL segment directly from REQUEST_URI $requestUri = isset($_SERVER['REQUEST_URI']) ? $_SERVER['REQUEST_URI'] : '/'; $path = parse_url($requestUri, PHP_URL_PATH); $segments = explode('/', trim($path ?: '', '/')); $firstSegment = $segments[1] ?? null; if ($firstSegment && isset($config->templateSegments[$firstSegment])) { $folder = $config->templateSegments[$firstSegment]; $config->urls->templates = "/site/" . $folder . "/"; $config->paths->templates = $config->paths->site . $folder . "/"; } Works well. in site/init.php I have a ProcessPageView::execute hook so that PW can find the template file and offer the "View" link in the page edit screen in admin. $wire->addHookBefore("ProcessPageView::execute", function (HookEvent $event) { // set templates dir for magazine pages in admin /** @var Pages $pages */ $pages = wire()->pages; /** @var PagesRequest $request */ $request = $pages->request(); /** @var Page $page */ $page = $request->getPage(); $editPage = $pages->get(input()->get('id')); if($page->template == 'admin' && $editPage->template == 'magazine-page') { /** @var Config $config */ $config = wire()->config; $folder = 'templates-magazine'; $config->urls->templates = "/site/" . $folder . "/"; $config->paths->templates = $config->paths->site . $folder . "/"; } }); Not the most elegant implementation, but works. Could have put this in site/templates/admin.php but decided against for separation of concerns reasons.1 point
-
Mothers are the best beta-testers haha. Maybe the change in the copy is indeed too subtle, but in that case maybe I’d go with your proposal of the Trash icon and the tooltip, shown when you cleared the main language. But like you said in this case this is more related to core than Fluency.1 point
-
I'm almost always configuring my templates to automatically update the page name based on the title 😉 Yeah, nice! But still, my point is to make it more obvious to the user to not forget to translate. I always test these things with my mother and this is eye-opening from time to time! 😄 She can not type blindly. So she types, then looks up on the screen. I bet a lot that she would not realise the change from "translate to all languages" to "clear all languages" after she typed or hit backspace. I updated my post with some new screenshots of mockups. I like it because it would be obvious but it would also cause the UI to jump around because it moves the input down. I tried to avoid that with where I placed the ui elements.1 point
-
I feel like this is something the editor should know / be told about — the same way editing a page’s title doesn’t automatically update its name — and not something so prominently shown (adding a new button). At first I was thinking of a hook checking for a change in the main language and then adding a message to the Inputfield indicating they might want to update the other languages as well, something like this: But then I thought it could be more subtle / embedded within Fluency’s UI, maybe the button’s text could be "Translation Available" when idle, "Translate to all languages" when main language is changed (non-empty) and "Clear all languages" when the main language is cleared / empty AND the other languages have a value (otherwise, default to "Translation Available"):1 point
-
I sketched my ideas to come back and share them with the people who suggested the feature and I haven't worked on any true implementation yet. I can assure you there's no rush, I wanted to get some feedback before diving in and coding everything. If I had made a decision in private, programmed everything, then come back and announced the new changes it would be far more work to change my approach if it had a negative reception. Luckily the custom header actions are 20 lines of code and aren't a commitment.1 point
-
@protro I use this module with htmx and it works nicely. It's pretty easy to do and it can all be done in HTML without handwriting JavaScript or parsing JSON. Here's a simple example. It should work, it may need tweaking but the concept is accurate. <!-- Your search form --> <style> .search-box { position: relative; } .search-indicator { align-items: center; display: flex; inset: 0; justify-content: center; opacity: 0; pointer-events: none; transition: opacity .3s; } /* Style your AJAX indicator as you please */ .htmx-request .search-indicator, .htmx-request.search-indicator { opacity: 1; pointer-events: auto; } </style> <div class="search-box"> <form hx-get="the search URL here" hx-target="#search-results" hx-disabled-elt="button[type=submit]" hx-indicator=".search-indicator"> <input type="search" inputmode="search" name="q" placeholder="What would you like to find?"> <input type="submit" value="Search"> <div id="search-results-container"> <!-- Search results will load inside this div --> </div> </form> <div class="search-indicator"> <span>Searching...</span> </div> </div> hx-get tells htmx to request the page from the URL you provide hx-target tells htmx where to put the markup that it receives back from the AJAX request, it accepts any CSS selector hx-disabled-elt directs htmx to disable the submit button during the request to prevent people from clicking the button multiple times, it accepts any CSS selector hx-indicator isn't required, but tells htmx which element to add the .htmx-request class while the request is in flight and then remove it when the results are loaded for a nice "loading" display. It accepts any CSS selector On the search page all you have to do is render the results that will appear inside #search-results-container, just markup. This is a rough example, but just illustrates how simple it can be. You'll have to tailor this to your needs. You can probably use markup that the SearchEngine module generates, but I haven't used that before myself. <div id="search-results"> <?php if ($searchResults->count()): ?> <ul> <?php foreach ($searchResults as $result): ?> <li> <p><?=$result->title?></p> <a href="<?=$result->url?>">View Page</a> </li> <?php endforeach ?> </ul> <?php else: ?> <p>There were no search results for "<?=$sanitizer->entities1($input->get->q)?>"</p> <!-- Thanks to teppo for reminder to sanitize --> <?php endif ?> </div> That's the only markup you need. You'll probably need to do some additional work to make things like paging happen, but it's all doable. I cobbled this together based on some code I've already written so it's just a starting point and probably needs some tinkering. Here's a handy reference of htmx attributes that will let you do anything you need.1 point
-
I was able to temporarily fix the problem by moving $this->addSseEndpoints(); from init() to ready(). After that, everything worked immediately. It now looks like this: public function init() { wire()->addHookAfter('/rockcalendar/events/', $this, 'eventsJSON'); wire()->addHookAfter('/rockcalendar/eventDrop/', $this, 'eventDrop'); wire()->addHookAfter('/rockcalendar/eventResize/', $this, 'eventResize'); wire()->addHookAfter('Page::loaded', $this, 'inheritFieldValues'); wire()->addHookAfter('ProcessPageEdit::buildFormContent', $this, 'hookRecurringEventEdit'); wire()->addHookProperty('Page::isRecurringEvent', $this, 'isRecurringEvent'); wire()->addHookAfter('ProcessPageEdit::buildFormDelete', $this, 'addTrashOptions'); wire()->addHookAfter('ProcessPageEdit::buildForm', $this, 'openDeleteTab'); wire()->addHookAfter('Pages::trashed', $this, 'hookTrashed'); wire()->addHookAfter('ProcessPageList::execute', $this, 'autoCloseModal'); } public function ready(): void { $locale = $this->getUserLocale(); if ($locale) { wire()->config->js('RcLocale', $locale); } wire()->config->js('RockCalendar', self::translations()); $this->addSseEndpoints(); } It works fine like this. Am I in for another surprise now? 🙂1 point
-
We've been working on a project in ProcessWire for the x time, and the more we use it, the more amazed we are by what this incredible CMS can do. From an SEO, developer, usability, and customization perspective, it’s truly outstanding. My team was deeply involved with Joomla! for 10 years - since its foundation - so we’ve seen a lot. After years of using ProcessWire, I just want to thank @ryan and everyone who has contributed - whether through code, ideas, support, or anything else. What a beauty, what a powerful CMS! 🚀1 point
-
1 point
-
Thank you very much @FireWire I've added them to the repo and they will be part of the next release ❤️1 point
-
Since I had to update more and more projects lately and also the PHP version of some of these projects was set to >=8 in the meantime I created a fork of the module and updated mPDF to version 8.1.3. With only some small changes in the WirePDF module I can now continue to use Pages2PDF without any restrictions. Maybe this is helpful for someone. https://github.com/markusthomas/Pages2Pdf1 point