-
Posts
653 -
Joined
-
Last visited
-
Days Won
47
Everything posted by FireWire
-
The lastrun log file accumulates a lot of entries and is never automatically pruned/cleared. Production server has a ~50mb file with 1.5 million entries. The log file contents are not written in a way that ProcessWire can parse. Is this log file necessary for RM to function properly? The log entries are accumulating even when migrations are disabled.
-
@ryan Safe travels π
-
@bernhard I really like this direction with adding something next to the languages, it makes a lot of sense and does a good job showing the relationship between the button to what it does. The only concern I have is that on fields with smaller widths a larger tab size will cause some crowding next to the language tabs and cause wrapping. Example would be the description fields for images. Real world example for me: If it could be a little more minimal it would fit in a lot of places, especially if there are many languages. Experimenting with an alternate "X" style icon to differentiate it from the trash icon used to delete blocks, groups, pages, etc. Hover state A popup with a similar message would confirm both the intention and purpose of the button. Perhaps "Delete content in all languages for this field? Cancel/OK". A "delete all" action would prevent having to first manually remove the contents of the default language then click to delete the contents for all other languages. A tooltip would show "Delete content for this field in all languages". With both a tooltip and confirm popup the user would see, understand, and remember its purpose when editing content anywhere in the admin. Thoughts?
- 305 replies
-
- 2
-
-
- translation
- language
-
(and 1 more)
Tagged with:
-
Entirely understand, a task not for the faint of heart. I haven't had to implement RRule myself but I've reviewed enough documentation to know that your work is tough, but incredibly appreciated. So I offer a message of support and encouragement π I have a project in dev right now that I'd be pleased to use for testing if/when you need it.
-
@bernhard Sure thing when I can get a chance. Maybe this weekend. In the meantime, if you're importing an svg you may have some success taking a look at the markup and seeing if there's anything extra that may be added by Affinity. I had a graphics program that liked to create a lot of attributes and stuff that wasn't needed. No guarantee that's the cause but it may help. Think the List.svg button in the repo is an example of one that has good markup with no extras. That's the best guess off the top of my head.
-
Hey @bernhard & @monollonom I didn't forget about you, just hammering out some work. Taking notes from your great input. I appreciate it! Will be back when I escape from programming prison π€£
- 305 replies
-
- 2
-
-
- translation
- language
-
(and 1 more)
Tagged with:
-
@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.
- 305 replies
-
- 2
-
-
- translation
- language
-
(and 1 more)
Tagged with:
-
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.
- 305 replies
-
- 1
-
-
- translation
- language
-
(and 1 more)
Tagged with:
-
I'm adding a header action with something similar to the following: Inputfields.addHeaderAction('title', { label: 'Some custom actions', icon: 'fa-question', menuItems: [ { label: 'Option 1', href: 'https://somedomain.ddev.site/admin/page-to-show/', modal: true, active: true, callback: null, }, { label: 'Option 2', callback: function() { ProcessWire.alert('Shows option 2'); }, active: true, }, { label: 'Option 3', callback: function() { ProcessWire.alert('Shows option 3'); }, active: true, }, ] }); When there is a combination of types of actions then the options that execute a callback will trigger the option that executes a href/modal. When clicking the option that opens a modal, the other options are not triggered. Example that opens the "Logs" page in a modal. Clicking "Option 2" executes both the callback and opens the modal in "Option 1": The same occurs if "Option 3" is clicked. I'm trying to figure out if this is something I'm doing wrong or if there's a bug when mixing option types. I was able to create a workaround by adapting this code by @bernhard that uses a callback to programmatically open a modal: Inputfields.addHeaderAction('title', { label: 'Some custom actions', icon: 'fa-question', menuItems: [ { label: 'Option 1', active: true, callback: function() { const link = document.createElement("a"); const $link = $(link); $link.attr('href', 'https://moduledev.ddev.site/admin/setup/logs/'); $link.addClass('pw-modal'); $link.on('click', pwModalOpenEvent); $link.on('pw-modal-closed', () => $link.remove()); $link.click(); }, }, { label: 'Option 2', callback: function() { ProcessWire.alert('Shows option 2'); }, active: true, }, { label: 'Option 3', callback: function() { ProcessWire.alert('Shows option 3'); }, active: true, }, ] }); This works but doesn't use the native API. Anyone have any insights that could help? Many thanks!
-
- 1
-
-
@bernhard I like your thinking π€ @Tiberium I'm glad you chimed in as well. Good to know that there are many people that will benefit from a new feature. Here's the UI I'm working towards: Going to create a new header action for translation related features. This will keep the UI tidy, clear all will be enabled by default, and doesn't need an option to enable/disable it on the module config page. @bernhard The icon to show the translator will be moved from the icon next to the translation button to the menu for consistency, since it's hover there won't be extra clicks. It will of course politely ask you if you are sure you want to nuke all of the content... I like this implementation because it will provide a good location for possible future features as well without crowding UI for fields. It will take a little bit to implement, I'm trying to keep up with work and I think I caught a bug with the custom header actions in PW core. I'll tag you both when it's on the dev branch so you can take it out for a test drive.
- 305 replies
-
- 2
-
-
- translation
- language
-
(and 1 more)
Tagged with:
-
I like to live dangerously* *please don't live dangerously Thank you for the correction of my oversight @teppo. I've edited my example to include that in case someone doesn't make it further down the comments π
-
@bernhard I was working on some blocks in RPB and noticed that there were some edge cases where changes weren't being detected by RPB. I ran into this with the trash icon on RepeaterMatrix items. Clicking it checks a hidden checkbox programmatically and doesn't emit a change event, so it's pretty much invisible to everything else that isn't RepeaterMatrix code. I added this mutation observer to InputfieldRockPageBuilder.js to watch for elements that have had the 'InputfieldStateChanged' class added. // trigger changed event when InputfieldStateChanged is added to elements $(document).on('ready', function () { const rpbItemsObserver = new MutationObserver(mutations => { mutations.forEach(mutation => { if (mutation.target.classList.contains('InputfieldStateChanged')) { RockPageBuilder.changed(mutation); } }); }); $('.rpb-items').each(function (_, rpbItem) { rpbItemsObserver.observe(rpbItem, { childList: true, subtree: true, attributes: true, attributeFilter: ['class'] }); }); }); In my testing this took care of some edge cases where changes aren't visible to RPB. Could be helpful for handling other sneaky inputs as well π
-
@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.
-
I do want to keep the scope of Fluency focused, but I'm comfortable with extending what it provides modestly. It would be a similar to how Fluency adds the content change indicators to tabs. It isn't something specific to translation functionality, but because Fluency provides the ability to do "mass translation" across multiple languages it's something that is helpful. I think that a "clear all" type of button is something in the same spirit. If Fluency can generate large amounts of content, it may be useful to have an extra tool to make working with it a little easier. It's the "enhancement" part of the "translation enhancement suite for ProcessWire" π ha! I am weary of going too far beyond and making Fluency intrusive. Maybe adding it as a config option, off by default, to enable that can be helpful and stay out of people's way.
- 305 replies
-
- translation
- language
-
(and 1 more)
Tagged with:
-
@bernhard I had a response typed out, didn't click "Submit Reply" and just came back find out that you never saw it π€¦ββοΈ Not clearing is intentional. The only way Fluency works right now is to take the source content and make the request to ProcessWire, pull from cache, or make a call to the translator API, then send it back to the client and replace the contents. At one point I think it may have cleared it but I updated the module to prevent taking any action if the source field is empty since it saved a round trip and an empty call to the translation API. Since Fluency is for translating and adding some nice-to-have things like the content change indicators on the tabs, maybe a secondary button off to the right to "Clear all content" would be useful? That could be a more intentional UI feature. What do you think? Worth doing?
- 305 replies
-
- translation
- language
-
(and 1 more)
Tagged with:
-
@bernhard That was very helpful, thank you for taking the time to explain more. I definitely don't want to replicate past ideas or force RC into trying to be something it isn't! This is an interesting idea. I'm understanding your approach better now and I think that my concept was too focused on having the RockDateRangePicker field do "too much". I'll share a little more about what I got wrong when using RC. When I opened the original event and saw the RDRP field it was confusing since it automatically shows the date and "Recurring" is checked, to indicate that this is a recurring event, but the contents of the RDRP field do not match the schedule/recurrence that the event was created with. If I uncheck "Recurring" and save the event page, nothing is changed with the other events, so I was confused on what the purpose of the Recurring button, schedule, list of dates, etc. was for. Even though you labeled it "Create Additional Events", I was focused on the UI since it presents things to interact with. The other part where I stumbled was the "This event is part of a recurring series" message. It made me think that clicking on "Click here to edit the main event" had something to do with the recurrences since it showed the other buttons below the date field. Since this occurrence isn't the "main" event, would it be a good idea to remove the "Recurring" and "Range" buttons and only allow for setting/editing the time? I used Thunderbird for my email/calendar client and took a look at how the UI works. I had never thought about it before and it's also more simple than the suggestion I was making, and might be more inline with RC's approach. I made a quick video and if managing recurrences could be something like this it would work really well. The Thunderbird UI, date selection, calendar style, etc. can all be ignored of course. Here are the steps I took: Create an event that occurs every Tuesday Edit the event and change it so that it occurs every Wednesday Move one of the occurrences in the series to Thursday Edit the event to change it back so it occurs every Monday calendar_events.mp4 What is interesting is that moving the one occurrence to Thursday "detached" it from the schedule. It is still a part of the main event, but the date is no longer managed by the recurrence rule. So I was able to change back from every Wednesday to every Monday and that individual occurrence was not changed. Any further edits to the schedule, like changing it to Monday of every other week, would also not affect the occurrence I moved to Thursday. Maybe the "generator" UI only appears when you create the event and then afterwards it only lets you edit the recurrence rule without displaying or managing any of the individual pages. Thunderbird does not have any "central" manager for all events the way that Recurme did or in the way that I was suggesting. It only allows you to adjust the schedule and doesn't let the user get involved any deeper than that when dealing with the schedule. Like RC, the calendar UI is used to manage individual occurrences. Interested in your thoughts. This is different than what I was originally thinking and perhaps this style is more compatible with RC's approach. RC has the great approach by using pages as the way to store and retrieve data since it doesn't "fight" the ProcessWire style. I definitely don't want to stray from the formula π
-
@bernhard One of the other things that may be difficult for the end user is after creating a recurring event, there's no reference to the recurrence afterwards. So creating a recurrence with advanced options like this: Opening that event again only shows "Every day for 100 times" and the "Simple" view rather than "Advanced". It's not really possible to tell what the schedule is for a recurring event after creating it. It seems like the date/occurrence field is only a generator and can't be used to re-schedule, change, or manage the recurrences. Opening the original event should show how the events are scheduled, and then let you update it. It would be good to be able to delete existing recurrences by clicking the trashcan icon next to each. When changing or deleting recurrences the "Create Events" button could change to "Update Events" which re-run modifications/deletions to recurrence pages on the server. The client that will be using the calendar is coming from their site that was built using Recurme which isn't as powerful as RC but lets you view and edit the schedule. Without being able to manage events from one location I'm not sure how they will respond to losing the ability to do that.
-
@bernhard I'm having trouble with selecting the "All events of this recurring series" option when deleting an event. When I choose that option the event is deleted, then it shows a "This page has no process assigned" message. When I close the window, only that one event has been deleted and all the other recurrences are still present. deleting_recurring_events_all_in_series.mp4 If I open the next occurrence it shows "This event is part of a recurring series. Click here to edit the main event", but clicking on that opens the page that is in the trash. delete_recurring_event_parent_in_trash.mp4 When I click on the next event and attempt to delete it with the option "This and all following events", it still only deletes that one event and shows the "This page has no process assigned" message. delete_all_following_events.mp4
-
I knew that at some point but didn't connect it in my brain when I made the map feature. The other ones were made before I knew that. The rest of them are original. I just upgraded RPB and saw the notes on the module config page which was a good reminder π
-
Hi all (yet again)! I'm still at it with some new buttons added, now up to 28 in total. New buttons include Form, LightboxGallery, Map, and CalloutImage, as well as a reverse color CalloutImage. Happy building! π
-
An escape key binding could be implemented with a snippet of code that looks for a modal element with a class or attribute defining it as active. So a binding that looks for that and executes a click action on the nearest close button or programmatic closing may be doable. That's a hypothetical based on instances where I've implemented it in my projects though, so just a cursory thought. I find myself reaching for the escape key often to exit windows, so it would be a welcome feature if implemented!