Jump to content


  • Posts

  • Joined

  • Last visited

About BrendonKoz

  • Birthday 12/12/1980

Profile Information

  • Gender
  • Location
    Saratoga Springs, NY, USA

Recent Profile Visitors

3,213 profile views

BrendonKoz's Achievements

Sr. Member

Sr. Member (5/6)



  1. I'll try to spare you from the, "Why would you want to [...]" question, as there are any various reasons why someone would want/need to migrate one way or another. Because ProcessWire is a Content Management Framework that helps a developer create a Content Management System, it's so varied in how it could be created that it might not be a simple export and re-import. Custom tools might need to be built -- or you might be lucky if the site is simple enough, you could potentially take advantage of something like the Import/Export modules, but those are often purpose-built for singular purposes as well. With few exceptions, all content should be in the template files and in the database. With some properly crafted SQL queries, you could get the data that you need. You could then rearrange those SQL queries as an insert into WordPress -- or convert it into a format that WordPress has an importer for. If this is your website though, it looks fairly custom with page partials used to build out the full page. If you're not a developer, you might need the direct help of a developer.
  2. Personal opinion: I think if I were to make a decision on what I see about Payload, I'd probably (personally) opt for Statamic for two reasons: I'm more familiar with PHP, and since it's a file based CMS and can be run directly from a Git repository, it makes things simpler (even if the installation is, IMHO, ridiculously bloated: thanks Laravel). I see some level of inspiration in it by Statamic, Kirby, and maybe Wagtail, but obviously with its own take on it all. For Directus: I don't personally see that as a CMS - or at least CMS-first option. If I remember correctly (I might not), it was originally advertised as a visual data query builder, enabling the ability to connect to an absurdly large amount of disparate datastore solutions, and then (visually) build queries to concoct interfaces and/or reports related to that data. Can you build a CMS with it? Apparently so! Should you build a CMS with it? I suppose that depends on exactly what it offers. I haven't personally tried it, even though I've kept my eye on it in case I had a project that seemed to fit. So far I (unfortunately) haven't. (I kind of want to play with it. It looks ridiculously powerful.) All that said, I haven't tried either, so my involvement isn't exactly what you were hoping for. As far as RestAPI and GraphQL, are the related modules insufficient? (I know you said default modules, so my curiosity is only adjacently related.) I definitely enjoy comparing and re-evaluating tools though, so appreciate this hashed, and rehashed, and rehashed topic! 😊
  3. @dragan Absolutely excellent feedback. I'll need to take this all in and review it in more detail -- and as you suggest, run it through some screen readers. I'm completely unfamiliar with aria-live aspects, and (unfortunately) only mildly aware of aria itself. What I need is to take a course on accessibility. Reading about it is one thing - seeing it in practice and understanding it is another. ♥️ I definitely want to do better. What you're playing with above in the example is a static HTML mockup template, prior to ProcessWire integration. Although the interface is pretty much the same at the moment, it will divert as development continues, so if I do improve things, it won't be visible!
  4. Thanks, dragan! I very much appreciate you sharing what you know of accessibility in this regard. When I researched this, I specifically looked for guidelines related to "maps", interactive or otherwise. I figured with the number of shopping malls around the world, surely someone would've been sued a large enough amount of money to end up being forced to determine best practices. Unfortunately I was wrong. There isn't much out there aside from providing a text-based alternative, an audio-alternative for the text (if feasible), and high contrast colors and large text. I'll admit I can work on the high contrast, though that can come with a CSS media override via browser setting detection, though I still need to write those style overrides (and fix up my dark mode styles). From your two examples, I went the hidden DL (DT / DD) element route -- that's where the directions (on how to get to/find) related to each of the entered items within the repeater get rendered straight to HTML. I need to review the DL's aria attributes though, so thank you for the reminder! I haven't hidden the SVG via ARIA, but still need to think if that's the best decision here (it likely is). I'll also look over the CSS-Tricks article since it's more SVG specific and likely why I didn't see it. I'd be curious to see how simple it might be to implement into my SVG implementation. When I was looking, I read through things like these: Digital Maps & Accessibility Accessible Maps The first one mentions pointing out accessible parking and highlighting drop-offs and ramp access which I either forgot about, or this wasn't an article I read before (but instead was very similar). I'll have to add some supplements to this relating to outdoor access. The second one, from the W3C basically says that there aren't any guidelines because the level of detail in a map is too high, and the needs of the map and the person vary too much to directly identify any set rules (paraphrased).
  5. I should've put this topic into the Dev Talk forum section; my mistake! If a moderator wants to move it, by all means... 🙂 I'm sure this isn't the most elegant way to do this, but it's what I came up with in the time I had. I ended up using a (ProField) Combo Field (see attached image for schema) to store each individual object's attributes that I wanted to have some level of editability within the CMS, and then stored those in a simple Repeater field as part of the "floorplan" template. I'll lock down the class_name, class_addition, and svg_path fields to administrator level accounts as they will be maintained in a much more fragile way. I used a Pages::saveReady hook in ready.php to detect changes on the repeater template (all repeaters have a hidden system template) in order to read in a version of the floor plan SVG that had valid, but easily identifiable XML strings to be used for (dynamic) replacement - and then write out a modified version using said replacement. An example of that string is below -- the floor number is the only thing that differs between each {placeholder}-esque string. <g id="floor0_fill"></g> The hook would then loop through all of the data provided in each combo field to generate the layers as needed, and then save the new version of the SVG file, completed as expected. I'll provide the code below, but it's only intended as an example for what I did. // Floor plan page - dynamically generate the static SVG from a template, and saved page fields' data $wire->addHookBefore('Pages::saveReady', function(HookEvent $event) { // Get values of arguments sent to hook (and optionally modify them) $page = $event->arguments(0); if ($page->template != 'floorplan') return; // Only process if the content of the floorplan items has changed $changes = $page->getChanges(true); if (!isset($changes['floorplan_repeater'])) return; // Generate the individual item SVG element entries $repeater = $page->floorplan_repeater; $svg = []; foreach ($repeater as $item) { $name = $item->floorplan_item->name; $type = implode(' ', $item->floorplan_item->type); $path = str_replace("\n", "\n\t\t\t\t", $item->floorplan_item->svg_path); $level = $item->floorplan_item->level - 1; // fix offset as set from PW ComboField's Select type $class = $item->floorplan_item->class_name; $full_class = $item->floorplan_item->class_addition ? "{$class} {$item->floorplan_item->class_addition}" : $class; $svg[$level][] = " <g id='floor{$level}_{$class}' class='{$type} {$full_class}'> <a class='item' xlink:href='#content-skip'> {$path} <desc>{$name}</desc> <text class='label' x='40' y='70'>{$name}</text> </a> </g>"; } // Open the SVG template (floorplan-template.svg), replace the content where needed, and save to the final SVG file (floorplan.svg) $path = $this->wire()->config->path('templates') . 'svgs/'; $svg_template = $this->wire('files')->fileGetContents("{$path}floorplan-template.svg"); if ($svg_template === false) { $this->error("The SVG template file could not be found: \"{$path}floorplan-template.svg\"", Notice::log); return; } foreach ($svg as $index => $floor) { $svg_template = str_replace('<g id="floor'.$index.'_fill"></g>', implode("\n", $floor), $svg_template); } $this->wire('files')->filePutContents($path.'floorplan.svg', $svg_template); }); It took me quite some time to find the proper way to identify a file path in ready.php!! That alone might be useful to someone. PW's filePutContents method (which also sets chmod) needed a path formatted in a specific way before it would work, and I wanted to do it the PW way, rather than the standard PHP way. Anyway, moving on... At this point all of the data was in the database, the SVG was generated dynamically from a template, and I moved on to dynamically generating the hidden definition list elements (that provide directions to each selectable object on the map, per floor), and the form elements that filter which map object is being highlighted on the map (with directions) at any given time. Lots of class/id/data massaging trickery, for sure! ...like the one below which was especially fun (and extremely ugly code). // Example Output: <span class="badge">G</span> <span class="badge">2</span> // Example Input: [0 => 'ground', 2 => 'two'] $badges = '<span class="badge">' . implode('</span> <span class="badge">', explode(',', str_replace('0', 'G', implode(',',array_keys($properties['floors']))))) . '</span> '; 😅 It's all working as of today, I only have some cleanup and optimizations to do - and the staff have just decided to do major furniture changes. 🤦‍♂️ At least the coding part is done! Back to the drawing board on the Illustrator file though!
  6. Hi @Robin S, and thank you for the reply! That's a good workaround. I was too focused on the oddity to even consider that. That said, in your opinion, do you think it is fairly safe to say that the limitation exists? I don't know if it's a bug, per se, or just a limitation -- but unless my attempts to search for "zero" in the forums was just too broad, I couldn't find anything that mentioned it. Do you think it should be submitted as a bug, or as a documentation update request? (I'm thinking the latter is simpler.) EDIT: Actually, it seems that the ProFields Combo doesn't support the x=y|z format, only x=y. That'd be a different forum though so since it's related I will followup there. For now I'll have to adjust my IDs to start from 1, and make sure to remember this when using it as output.
  7. The default IDs created for a Select Fieldtype seem to start from the numerical digit of 1. However, we're supposed to be able to define our own custom id and title values. In my case, I was trying to assign a value of zero as the ID assigned to the first title so that sort order could be properly maintained (floors of a building, where "ground" = 0). From my tests, with the standard Select Fieldtype, the ID is redefined automatically as the largest numerical value (ex: 0:ground, 1:floor 1, 2:floor 2, 3:floor 3 - ID for "ground" becomes 4). For the Combo field's internal value of a Select, its ID value ends up becoming null. I couldn't find if this is a documented and known limitation anywhere and am wondering if I'm just doing something silly. Trying to force the ID back to 0 will prompt the user to delete the associated entry. After trying to update the ID for "ground" to a numeric value of zero:
  8. If you want to be sure to support Firefox, it's still best to develop in Firefox. Once finished, you then just need to visually inspect (under various viewport resolutions) with other browsers. Chromium supports more CSS and other technologies before other browser rendering engines, so if you develop to Chrome and then go back to Firefox to fix something, it's very often a forced regression type of fix, which isn't fun. Even worse is Safari... Very happy to see that you had the forethought to include (or in this case, exclude) printable formatting! The attention to detail is great. Congratulations on your launch!
  9. I worked for quite some time coming up with this mock-up interface which originated from an architectural PDF of our building's floor plan. It's a (partially convoluted) interactive SVG, taking advantage of CSS and JS, along with a form control to highlight areas on the map, swap out active floor(s), and provide textual directions on how to find the particular location within our building (there's no good studies on accessibility for maps, so it's my best attempt at an accessible alternative/supplement for the SVG image). Example page in question. I'd like to, if possible, get the location name and description (directions) to be powered internally by ProcessWire. Each item also has required attributes: Level (floor) Attribute type: Collection, Service, Collection, Location An identifier that matches the SVG's hardcoded object path. (Ex: identifier is "space.glasby" points to #sspl-floorplan .space.glasby .item -- in this scenario, "space" could also refer to its attribute type) The biggest problem is that the SVG is not created dynamically, it is manually created/maintained from an Illustrator file, exported as SVG, and then customized with classes and IDs. So, currently, ProcessWire would need to be able to examine the structure of the SVG to identify items (and at a minimum, its floor and attribute type). I've been trying to think of a way to allow for integration for a couple weeks now, but I'm a little stumped. While creating the mock-up I was not considering that the data would need to come from somewhere and unfortunately(?) took complete advantage of static content. Now I'm not sure how I'd re-integrate things. All of the text that is displayed directly on the map is part of the SVG itself, so if it's to be powered by ProcessWire, I'm not sure if replacing it with JavaScript, re-processing it on save, or converting it to a PHP file (to allow dynamic string interpolation from a data source) would be the best solution here...or if I should admit defeat and leave it all as static content. I now have an idea of how to proceed, but I'd love to hear how you might've solved this, either from the beginning, or from my current sticking point above. I'm going to use a separate PHP (template for the SVG) file that will generate all of the various shapes except for objects/structures that will not change, and insert them dynamically into the SVG, and then overwrite the static SVG with what is generated; this will allow me complete control over the markup. This will get run on save of the ProcessWire page file. Unfortunately this means that I'll have to store the SVG path string in the associated field in ProcessWire as well. I suppose that's one (giant) step away from integrating an SVG drawing tool.
  10. I feel bad bumping this topic, but I think some people might've missed, or misunderstood the importance of the reasoning for looking towards moving away from CKE4. The codebase of CKE version 4 will essentially be abandoned as of sometime in 2023 by the organization that maintains it. Considering the large amount of security issues that are consistently discovered in heavily used input/output handling JavaScript packages (whether due to custom add-ons or its core), and the fact that Ryan strives for a very secure system... The need to provide an alternative WYSIWYG module is evident. CKE5 seems like the least intrusive option (for users/clients). It appears as though he hopes to make it fairly seamless for site administrators and developers, but the integration changes aren't a 1:1 swap, so he'll have quite a bit to consider. It's likely that you'd still be able to use CKE4 as a module, just like you could continue using TinyMCE when it was removed from core -- as a separately installable module. If you wish to use standard textarea fields or Markdown-powered fields, there are add-ons for those too (already). You will still have choice, and that's one of the excellent things about ProcessWire. The only issue here is that Ryan wants to make sure that you and your clients have a stable, secure, and usable system. As always, you will still have control over your own system(s). ♥
  11. I don't suppose there's any chance of getting these juicy forum board solutions added to related module documentation as Examples, could we? These are great starting points to common scenarios! The downside would be maintaining them for compatibility, but perhaps explicit notices with dates that the examples were created? So often I end up searching the website for answers to questions, but they're all over the place - the blog, documentation, api, forum (and not always the module forum). 😉 Just a thought. That said, loving these examples you're providing from actual client work you're doing. Thanks, Ryan!
  12. Ah, that's more than I knew. In that case this is good for me to know about too! Thanks for that, and for your module solution!
  13. A very nice and clean solution! Should your needs grow from this, you might enjoy one of the following options as well: Field Descriptions Extended Process Documentation
  14. Although you can no longer signup for a new account to use the embedded Google Translate widget, you can still take advantage of it. I'll provide my solution should it be useful to anyone else. Having multiple options, depending on need, can be useful. <div id="google_translate_element"></div> <!-- Google Translate --> <script type="text/javascript"> function googleTranslateElementInit() { new google.translate.TranslateElement({pageLanguage: 'en'}, 'google_translate_element'); } </script> <script type="text/javascript" src="//translate.google.com/translate_a/element.js?cb=googleTranslateElementInit"></script> I've used this CSS to style it from its default, while still providing the (likely) required credit to its tool. #google_translate_element .skiptranslate { visibility:collapse; text-align:center; position:absolute; width:100%; width:calc(100% - 4rem); top:0; } #google_translate_element .skiptranslate * { margin:0 auto; display:block; } #google_translate_element .skiptranslate [id*=targetLanguage] { visibility: visible; } #google_translate_element .skiptranslate [id*=targetLanguage] select { border:1px solid rgba(0,0,0,.2); background-color:#F4F6F7; color:rgba(0,0,0,.7); } #google_translate_element .skiptranslate [id*=targetLanguage] select option { background-color:transparent; } #google_translate_element [id*=targetLanguage]::after { content:'Powered by Google Translate'; display:block; text-align:center; line-height:1; color:rgba(0,0,0,.6); } @media(max-width:575px){ #google_translate_element .skiptranslate { width:calc(100% - 2rem); } }
  15. In the InputfieldEvents.module file's ___processInput method, there's an Exception exclaiming, "This inputfield requires that you set valid 'page' and 'field' properties to it." In what instances do inputfields (or any type of module) require page and field properties? I notice that many do not require this, but am not sure of the circumstances when they are required. So far I've just been copying/pasting from similar modules without truly understanding why.
  • Create New...