Jump to content

Chris Bennett

  • Posts

  • Joined

  • Last visited

  • Days Won


Chris Bennett last won the day on May 12

Chris Bennett had the most liked content!

Recent Profile Visitors

790 profile views

Chris Bennett's Achievements

Jr. Member

Jr. Member (3/6)



  1. Thanks to the excellent feedback from @matjazp , have re-vamped way the whole module works. Minimizes potential conflicts and was just a better idea. Now draws CSS variables, conditionally loaded source CSS and framework CSS together to generate single minified CSS file, with version control link to refresh cache for other pages. Only occurs when the module is visited, as it should, and after that other pages draw the minifed CSS straight from cache. Now loads in parallel with other CSS. at somewhere around 30ms, same as other CSS files. First load (in the module itself, not subsequent pages) comes in around 17 kB compressed (somewhere around 96kB uncompressed and with all options selected), so considerable improvement, especially given the elimination of almost all processing overhead. Very happy I was prodded into action. Took a little time, but I am much happier going forward. As part of the re-working, I am in the process of splitting up CSS for conditional loading according to user selections. Opens up a far greater range of user options, which I am rolling out to module as I go. As a bonus, splitting the source CSS up is making it easier for me to track and alter, allowing me to simplify the CSS and balance specificity better. Always nice when file sizes are going down, not up even though you are adding new stuff :)
  2. https://github.com/chrisbennett-Bene/AdminThemeTweaker Inspired by @bernhard's excellent work on the new customisable LESS CSS getting rolled into the core soon, I thought I would offer up the module for beta testing, if it is of interest to anyone. It takes a different approach to admin styling, basically using the Cascade part of CSS to over-ride default UiKit values. Values are stored in ModuleConfig Module creates a separate AdminThemeTweaker Folder at root, so it can link to AdminThemeTweaker.php as CSS AdminThemeTweaker.php reads the module values, constructs the CSS variables then includes the CSS framework Can be switched on and off with a click. Uninstall removes everything, thanks to bernhard's wonderful remove dir & contents function. It won't touch your core. It won't care if stuff is upgraded. You won't need to compile anything and you don't need to touch CSS unless you want to. It won't do much at all apart from read some values from your module config, work out the right CSS variables to use (auto contrast based on selected backgrounds) and throw it on your screen. You can configure a lot of stuff, leave it as it comes (dark and curvy), change two main colors (background and content background) or delve deep to configure custom margins, height of mastheads, and all manner of silly stuff I never use. Have been developing it for somewhere around 2 years now. It has been (and will continue to be) constantly tweaked over that time, as I click on something and find something else to do. That said, it is pretty solid and has been in constant use as my sole Admin styling option for all of those 2 years. If nothing else, it would be great if it can provide any assistance to @bernhard or other contributor's who may be looking to solve some of the quirkier UiKit behavior. Has (in my opinion) more robust and predictable handling of hidden Inputfields, data-colwidths and showIf wrappers. I am very keen to help out with that stuff in any way I can, though LESS (and any css frameworks/tools basically) are not my go. I love CSS variables and banging-rocks-together, no-dependency CSS you can write with notepad.
  3. Weird edge case, which has me scratching my head. Background: API-added button to delete selected files exhibits (maybe) weird behavior when save is triggered by custom js. As soon as the InputfieldSubmit field is there, it intercepts/captures the javascript trigger instead. Almost like validation or as if it's acting as an anchor. It definitely seems like the inclusion of that InputfieldSubmit causes the unexpected (by me) behavior. Have tried multiple different workarounds to troubleshoot: deleting trigger does nothing deleting hook does nothing moving InputfieldSubmit outside MarkupAdminDataTable does nothing changing name and/or id of InputfieldSubmit does nothing If the new InputfieldSubmit is there, it 'catches' the custom js save trigger. If the field is not added (or hidden then loaded by AJAX), then the custom js trigger happily clicks the save_submit id, and page save happens, as expected. console.log confirms 'submit_save' is the element' the js was targeting. The js save hangs, and window.parent.document.activeElement (and your eyes) confirm the new InputfieldSubmit button is now the active element. Setting InputfieldSubmit as button prevents the weirdness, but doesn't provide the desired functionality. As type=submit, the files are deleted snappily, and the refreshed page is displayed showing they are gone. So it's very much a weird edge case, but I'd love to know what is happening behind the scene if anyone has any ideas or experience with similar issues. Simple custom js is below: if (input.classList.contains('autoSaveOnChange')){ if (input.classList.contains('autoGenerateNew')){ var generateCheckbox = getById('Inputfield_generateNewFavicons'); var showAdvanced = getById('Inputfield_showAdvanced'); generateCheckbox.checked = true; showAdvanced.checked = false; }; input.closest('.InputfieldContent').classList.add('saveLoading'); var saveSubmit = getById('submit_save') || getById('Inputfield_submit_save_module'); //console.log(saveSubmit) saveSubmit.click(); } InputfieldSubmit is added as follows: // Add in button to delete fields $button = $this->modules->get('InputfieldSubmit'); $button->attr('id+name', 'deleteSelectedFolders'); $button->value = 'Delete selected folders'; //button->type = 'button'; auto save works with this, but hook does not $field->add($button);
  4. Hi Kaz, I am by no means an expert. It *could* be a problem with the actual server variables, had a little "fun" with that end, working out what had changed when Siteground made some changes. In my case, setting the timezone properly (again) solved my server problem. Re: config my locale mirrors yours with the exception of setting $config->timezone as well. $config->timezone = 'Australia/Brisbane'; setlocale(LC_ALL,'en_AU.UTF-8'); Hope you get it sorted, sorry I can't be of more assistance.
  5. Thanks Bernard! The mobile preview bit is from the first pw module I am preparing to release into the wild, very shortly, FaviconMagic. Been using it for many months now, but wanted to make it shinier and stress test it before offering it up. Was complicated a little by the background admin styling, which is from another module I plan to release into the wild shortly ...have been using and tweaking it for around 2 years now, since we discussed admin theme tweaking strategies. Just tweaking FaviconMagic now, adding features and trying to break it so I can make it better. Planning to throw it up on Github soon - probably within the week - depending on how much stuff I keep adding πŸ˜‰ FaviconMagic is kinda like realfavicongenerator, but I am aiming to take that up a notch (or two) for the processwire community. I have learned much and the processwire community have always been very gracious with their time and advice. Adds support for svg favicons (cutting out unnecessary downloads), autogenerates a maskable favicon, generates webmanifest and browserconfig etc. Basically a shortcut to full PWA requirements, minus the service Worker stuff. You can generate new favicons and play around with a whole heap of stuff without leaving pw admin. Also uses "smarter" options. For example, short_name is apple app name, unless you choose to over-ride it. Theme color is similar, you don't need to cut and paste the same stuff multiple times, but advanced config is always available if you desire it. Apart from a one-off include in the head of the target doc, there is no copy/paste of markup. Always up to date with your latest tweaks. No unzipping either. Generation of all png variations from svg resizing for crispy goodness. More than happy to give you a yell when the beta is up on Github if you'd like, I would love to hear what you think.
  6. Many thanks Horst, confirmed my thinking. After happily and messily playing around, a tiny voice deep in my memory whispered "sandbox" ...sheesh. Been a while since I played around with sandboxed iframes, but the little voice from the past was right. Simple addition of sandbox to the iframe automatically prevents get/set of cookies. So I could get it doing what I wanted by adding: <iframe sandbox="allow-same-origin" src="..."> Apologies for not remembering sooner, I will be busily head-desking over in the corner now πŸ˜‰
  7. Edit: Belated memory that iframe sandbox exists, so there is a simple way to provide page preview as guest. <iframe sandbox="allow-same-origin" src="..."> Prevents get/set of cookies and scripts by default, so simple workaround. Drawback is that little things like your js dark mode etc won't be active either, but for simple preview needs bit easier than the other things I unsuccessfully tried. Page preview as guest from within admin... is there an easy strategy? If any wise heads have any ideas for how I can "log out" only from the iframed link or if there is a query I can pass with the iframe url, I would be very grateful. Can access the iframed url via js to change things, like successfully getting rid of scrollbars etc, but before I delve further along that route was wondering if there is an easier way. Making a little mobile preview for favicon generator/webmanifest thing I'm working on. Not really important (or necessary) - pretty much editor bling to provide instant feedback in a non-new, mid-range android. Working pretty well, with lots of irrelevant silliness like swapping colors of mobile top icons based on contrast. Frivolous but kinda fun. Homescreen / clickable app icon and short_name based on generated favicons and values. Click homescreen icon to start screen with theme color, app start icon and long name. Figured I'd throw in iframe of the site to round things out preview-wise. No problems there, but session remains as admin, so not really a "guest preview" with front-end editing styling, Tracy and various admin stuff.
  8. Slight adjustments to enhance use for 2021 and to remind me how I can make it work when I forget and need to use Google as my offline memory
  9. Very much appreciate the tip. Had taken a look with code inspector, but must have stuffed up my typing, then tried way too many other potential options. Next time, if in doubt I will use Tracy to confirm. Can't believe I didn't think of that, Saturday afternoon brain is not working as well as I would like. Many thanks again!
  10. Thank you Adrian, I love your work. Tried variations similar, but obviously not the right combo. You rock!
  11. Having no joy trying to find out how to trigger InputfieldRadiosFloated on InputfieldRadios via api for module. Basically just want same as Radio Button Column options on "normal" field. Guessing at what the magic words might be has not got me far πŸ˜‰ Figure it has to be do-able, and is probably easy, just can't work out how. Any help pointing me in the right direction, or at a good run down of the options in general would be very gratefully accepted.
  12. 2021 update These things change and get tweaked over time, as stuff always does. We can make the size declaration a little more relevant. Declare a selection of sizes for your svg to "encourage" chromium-based browsers to use it instead of the larger bitmapped 192x192 and other assorted icons. We also need to thread the needle to ensure app start icons don't get confused and end up with an icon that is smaller than desired. Declare it last, after your png fallbacks - last one that is suitable size *must* get the nod. Counter-intuitively, declare that your svg is 150x150. (adjusted for 2021) πŸ‘‰ "sizes": "48x48 72x72 96x96 128x128 150x150 256x256 512x512 1024x1024", { "name": "Alfresco bar + bistro, Eumundi", "short_name": "Alfresco", "description": "Relaxed outdoor dining on our spacious deck in Eumundi", "start_url": "/", "display": "standalone", "background_color": "#acbd72", "theme_color": "#acbd72", "icons": [ { "src": "https://www.alfresco-bar-bistro.com.au/site/assets/files/favicons/favicon-48x48.png", "sizes": "48x48", "type": "image/png", "purpose": "any" }, { "src": "https://www.alfresco-bar-bistro.com.au/site/assets/files/favicons/favicon-192x192.png", "sizes": "192x192", "type": "image/png", "purpose": "any" }, { "src": "https://www.alfresco-bar-bistro.com.au/site/assets/files/favicons/favicon-512x512.png", "sizes": "512x512", "type": "image/png", "purpose": "any" }, { "src": "https://www.alfresco-bar-bistro.com.au/site/assets/files/favicons/maskable-512x512.png", "sizes": "512x512", "type": "image/png", "purpose": "maskable" }, { "src": "https://www.alfresco-bar-bistro.com.au/site/assets/files/favicons/favicon.svg", "sizes": "48x48 72x72 96x96 128x128 150x150 256x256 512x512 1024x1024", "type": "image/svg+xml", "purpose": "any" } ] } Cross-Origin-Resource-Policy (CORP) manifest/icon bug A slightly-related testing note, if you are incorporating Cross-Origin-Resource-Policy (CORP) to enhance site security. Please note there is a chromium bug which affects chromium dev tools ability to properly display your manifest icons: Chromium DevTools bug: Cross-Origin-Resource-Policy prevents manifest icons from loading This long-term bug doesn't seem to affect the way the manifest itself works or the icons, just their display in Dev tools > Application > Manifest in Chrome, Edge, Brave, Opera... sheesh. Firefox Dev tools continues to happily display them without a problem. ------------------------------------------------------------------------------------ Quick tip for 2020 web manifests, which I couldn't find anywhere else. Wanted web manifest on Chrome/Edge to download the tiny favicon svg, instead of the larger 192x192 png it wanted to by default. Not a big deal, but mildly annoying: 15kb (non-scalable) png vs 1.5kb (infinitely scalable) svg. After a little head-scratching and fiddling around, came up with a solution that seems to do the trick. Declare it last, after your png fallbacks - last one that is suitable size *must* get the nod. Counter-intuitively, declare that your svg is 150x150. (adjusted for 2021) Mine isn't. Never has been, it's a scalable vector graphic. Simply declaring it is 150x150 in the manifest is enough to get the job done. Suspect the Chrome/Edge engine declares that any non-specified svgs are given that 150x150 size and anything else returns as a "fail". Without declaring a size on it, or declaring it as anything other than 150x150, it just wouldn't load. Weird, but works, so I'm happy 😊 { "name": "Longer App/Business Name", "short_name": "Short Name", "description": "Description of App/Business", "start_url": "/", "display": "standalone", "background_color": "#880000", "theme_color": "#880000", "icons": [ { "src": "favicon-192x192.png", "sizes": "192x192", "type": "image/png", "purpose": "any" }, { "src": "favicon-512x512.png", "sizes": "512x512", "type": "image/png", "purpose": "any" }, { "src": "maskable-512x512.png", "sizes": "512x512", "type": "image/png", "purpose": "maskable" }, { "src": "favicon.svg", "sizes": "150x150", "type": "image/svg+xml", "purpose": "any" } ] }
  13. Many thanks @BillH, I will certainly investigate that thread further, it expands on some of the snippets I tried unsuccessfully along the way. In the meantime, I lucked upon the thread below, thanks to Bernard posting, which got me a lot further along the path. Still experimenting, with a fair degree of success so far, but not yet ready to claim it is "solved". Enjoying learning more as I go. Module I am playing around with - mainly to force myself to learn more about how everything really works - is an attempt to recreate what I am already using (via normal admin page, a couple of fields with a nifty preview/review using RuntimeMarkup and a couple of php templates). It generates favicons from svg right the way through (unlike realfavicongenerator), with a fallback for pngs and all the necessary markup, manifest, browserconfig etc. Similar to realfavicongenerator (which I have long loved), but tweaked according to my personal wishlist. Could accomplish what is *needed* pretty easily, but would really like to add some polish for clients. Also so they can easily see what we have done and/or do that stuff themselves πŸ˜‰ The php templates I am currently using simply by accessing the normal hidden admin page automatically generate: svg favicons for current gen browsers (if svg source provided) black safari pinned tab mask icon and white mstiles (if svg silhouette provided) automatic mask icon with required safe space for webmanifest automatic cropping of svgs/pngs so small icons can use the whole 16x16 or 32 x32 - because 3 or 4 px makes a big difference when you only start with 16 generation of webmanifest and browserconfig frontend markup for inclusion that basically just checks if the right file exists and plonks in the correct markup if it does Was a little surprised it seemed to work well. No zip files, no code, no third parties, plonk new sources in, click generate new, check results and done. Lots more previews/config options I could/will add but figured it might be wise to work out any inevitable kinks with implementation of a module along these lines within the api before I got carried away too much more.
  14. Thank you @bernhard, @adrian and @kixe for this thread and the very timely thank-you note from Bernard that pointed my in a far more productive direction with regards to my question from yesterday: Had been playing around with hooks to try to achieve my goals but this has made things a whole lot better and a whole lot easier. I kinda figured there had to be a way to hook into the form build process, but without this thread I would have remained lost for much longer as I played around the edges. My very grateful appreciation to all!
  15. Hi all, I am going round and round in circles and would greatly appreciate if anyone can point me in the right direction. I am sure I am doing something dumb, or missing something I should know, but don't. Story of my life πŸ˜‰ Playing round with a module and my basic problem is I want to upload an image and also use InputfieldMarkup and other Inputfields. Going back and forth between trying an api generated page defining Fieldgroup, Template, Fields, Page and the InputfieldWrapper method. InputfieldWrapper method works great for all the markup stuff, but I just can't wrap my head around what I need to do to save the image to the database. Can generate a Field for it (thanks to the api investigations) but not sure what I need to do to link the Inputfield to that. Tried a lot of stuff from various threads, of varying dates without luck. Undoubtedly not helped by me not knowing enough. Defining Fieldgroup etc through the api seems nice and clean and works great for the images but I can't wrap my head around how/if I can add/append/hook the InputfieldWrapper/InputfieldMarkup stuff I'd like to include on that template as well. Not even sure if it should be where it is on ___install with the Fieldtype stuff or later on . Not getting Tracy errors, just nothing seems to happen. If anyone has any ideas or can point me in the right direction, that would be great because at the moment I am stumbling round in the dark. public function ___install() { parent::___install(); $page = $this->pages->get('name='.self::PAGE_NAME); if (!$page->id) { // Create fieldgroup, template, fields and page // Create new fieldgroup $fmFieldgroup = new Fieldgroup(); $fmFieldgroup->name = MODULE_NAME.'-fieldgroup'; $fmFieldgroup->add($this->fields->get('title')); // needed title field $fmFieldgroup->save(); // Create new template using the fieldgroup $fmTemplate = new Template(); $fmTemplate->name = MODULE_NAME; $fmTemplate->fieldgroup = $fmFieldgroup; $fmTemplate->noSettings = 1; $fmTemplate->noChildren = 1; $fmTemplate->allowNewPages = 0; $fmTemplate->tabContent = MODULE_NAME; $fmTemplate->noChangeTemplate = 1; $fmTemplate->setIcon(ICON); $fmTemplate->save(); // Favicon source $fmField = new Field(); $fmField->type = $this->modules->get("FieldtypeImage"); $fmField->name = 'fmFavicon'; $fmField->label = 'Favicon'; $fmField->focusMode = 'off'; $fmField->gridMode = 'grid'; $fmField->extensions = 'svg png'; $fmField->columnWidth = 50; $fmField->collapsed = Inputfield::collapsedNever; $fmField->setIcon(ICON); $fmField->addTag(MODULE_NAME); $fmField->save(); $fmFieldgroup->add($fmField); // Favicon Silhouette source $fmField = new Field(); $fmField->type = $this->modules->get("FieldtypeImage"); $fmField->name = 'fmFaviconSilhouette'; $fmField->label = 'SVG Silhouette'; $fmField->notes = 'When creating a silhouette/mask svg version for Safari Pinned Tabs and Windows Tiles, we recommend setting your viewbox for 0 0 16 16, as this is what Apple requires. In many cases, the easiest way to do this in something like illustrator is a sacrificial rectangle with no fill, and no stroke at 16 x 16. This forces the desired viewbox and can then be discarded easily using something as simple as notepad. Easy is good, especially when you get the result you want without a lot of hassle.'; $fmField->focusMode = 'off'; $fmField->extensions = 'svg'; $fmField->columnWidth = 50; $fmField->collapsed = Inputfield::collapsedNever; $fmField->setIcon(ICON); $fmField->addTag(MODULE_NAME); $fmField->save(); $fmFieldgroup->add($fmField); // Create: Open Settings Tab $tabOpener = new Field(); $tabOpener->type = new FieldtypeFieldsetTabOpen(); $tabOpener->name = 'fmTab1'; $tabOpener->label = "Favicon Settings"; $tabOpener->collapsed = Inputfield::collapsedNever; $tabOpener->addTag(MODULE_NAME); $tabOpener->save(); // Create: Close Settings Tab $tabCloser = new Field(); $tabCloser->type = new FieldtypeFieldsetClose; $tabCloser->name = 'fmTab1' . FieldtypeFieldsetTabOpen::fieldsetCloseIdentifier; $tabCloser->label = "Close open tab"; $tabCloser->addTag(MODULE_NAME); $tabCloser->save(); // Create: Opens wrapper for Favicon Folder Name $filesOpener = new Field(); $filesOpener->type = new FieldtypeFieldsetOpen(); $filesOpener->name = 'fmOpenFolderName'; $filesOpener->label = 'Wrap Folder Name'; $filesOpener->class = 'inline'; $filesOpener->collapsed = Inputfield::collapsedNever; $filesOpener->addTag(MODULE_NAME); $filesOpener->save(); // Create: Close wrapper for Favicon Folder Name $filesCloser = new Field(); $filesCloser->type = new FieldtypeFieldsetClose(); $filesCloser->name = 'fmOpenFolderName' . FieldtypeFieldsetOpen::fieldsetCloseIdentifier; $filesCloser->label = "Close open fieldset"; $filesCloser->addTag(MODULE_NAME); $filesCloser->save(); // Create Favicon Folder Name $fmField = new Field(); $fmField->type = $this->modules->get("FieldtypeText"); $fmField->name = 'folderName'; $fmField->label = 'Favicon Folder:'; $fmField->description = $this->config->urls->files; $fmField->placeholder = 'Destination Folder for your generated favicons, webmanifest and browserconfig'; $fmField->columnWidth = 100; $fmField->collapsed = Inputfield::collapsedNever; $fmField->setIcon('folder'); $fmField->addTag(MODULE_NAME); $fmField->save(); $fmFieldgroup->add($tabOpener); $fmFieldgroup->add($filesOpener); $fmFieldgroup->add($fmField); $fmFieldgroup->add($filesCloser); $fmFieldgroup->add($tabCloser); $fmFieldgroup->save(); /////////////////////////////////////////////////////////////// // Experimental Markup Tests $wrapperFaviconMagic = new InputfieldWrapper(); $wrapperFaviconMagic->attr('id','faviconMagicWrapper'); $wrapperFaviconMagic->attr('title',$this->_('Favicon Magic')); // field show info what $field = $this->modules->get('InputfieldMarkup'); $field->name = 'use'; $field->label = __('How do I use it?'); $field->collapsed = Inputfield::collapsedNever; $field->icon('info'); $field->attr('value', 'Does this even begin to vaguely work?'); $field->columnWidth = 50; $wrapperFaviconMagic->add($field); $fmTemplate->fields->add($wrapperFaviconMagic); $fmTemplate->fields->save(); ///////////////////////////////////////////////////////////// // Create page $page = $this->wire( new Page() ); $page->template = MODULE_NAME; $page->parent = $this->wire('pages')->get('/'); $page->addStatus(Page::statusHidden); $page->title = 'Favicons'; $page->name = self::PAGE_NAME; $page->process = $this; $page->save(); } }
  • Create New...