Jump to content

BrendonKoz

Members
  • Posts

    232
  • Joined

  • Last visited

  • Days Won

    3

Everything posted by BrendonKoz

  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.
  16. Going through this topic, I am hopeful the Intellisense after setting up VSCode will help me discover more in the core that's difficult to learn from external documentation. As much as I loved Atom and its graphical project viewer extension, the IDE capabilities are unfortunately problematic in my experiences. So here I am, giving VSCode another shot. Oh yes, since going through this topic, some have added extensions to their projects that VSCode has since added to the core editor, so some of you might be able to reduce the count of some of your extensions. Thanks to everyone for providing their findings (and snippets) so far! Color-coded bracket matching: Now in a core setting called Editor > Bracket Pair Colorization Renaming of matching HTML tags is part of the core via the rename ability (place cursor in/on tag name, press F2), though it currently doesn't work in PHP files (work in progress, I guess?) - alternatively, for simple matching replacements, you can double-click on the element name and press CTRL+D (or CMD+D on Mac) for automatic multi-select, then type the new tag name. These all have issues, so tag-rename or auto-rename-tag might still be preferred. Reformatting/Beautifying: SHIFT+ALT+F will automatically reformat the code of the file in focus, or currently highlighted code; also available from the right-click context menu (not yet sure how to define different formatting rules). URLs typed in the editor will be openable by default via CTRL+Click via Editor > Links. Not sure if people know, but it also offers code folding: CTRL+SHIFT+[ to fold/collapse, CTRL+SHIFT+] to unfold/open...or just use the caret symbols next to the text editor's line numbers. I think everything else (questioned raised) has been covered, or not yet able to be solved.
  17. Thanks for the feedback, Rick! In this case, I'm planning on allowing tags on every page that contains content. Although education-related, we're a public library, so we don't actually teach per-se, but the actual content has no limit. I hadn't yet attempted implementation yet so I wasn't aware ProcessWire doesn't allow multi-word tags, but that could potentially be solved with hyphenation. I'm mostly wondering what people have come up with in terms of rules or procedures on best-case scenarios for instructing users on how to take advantage of tags. I do realize, however, that this may be dependent upon implementation, though I'm curious of first-hand scenarios of others, to maybe apply to my own. (You kind of touched on an idea with the course category subset.) ? Thank you!
  18. So, just like naming variables, trying to come up with how to properly create tags that would be understandable, usable, and not "one unique tag per every item", how do you all go about creating your tagging system(s)? Do you give access to creating tags for your customers? If so, have you come up with instructions or ways to help them satisfy their desires without overloading the website visitors with unusable overabundance of named tags? I'm reviewing a secondary site for my current employer that I have not had control over, and with free reign, there are over 800 tags on about 200 pages (and many pages don't even have any tags assigned). Some tags are full sentences. I'll obviously need to describe what a tag is to my coworkers, but even I'm having a hard time coming up with proper ideas for tags, and how best to determine what would be good and what wouldn't. (We're a library and therefore deal in education, so topics can be extremely wide-ranging on any number of subject areas.)
  19. I had quite a bit of fun watching the intro video. It didn't really seem to (for me) add anything of value in terms of purpose or content, but it was fun - and different. If all websites started doing this I'd definitely be turned off, but in a case where it's a unique scenario and having some free time, it worked well. I'd be curious - if you're willing - to hear more about how you're handling the cookie consent to only allow scripts if/when a user allows it? It sounds like it's a fairly simple, yet robust solution, and since there are many various solutions to this, I'd be curious to hear yours (again, if you're willing to share). A well done, clean design overall! I might pop a link to this over to Jack McDade (yes, Statamic's Jack McDade) since he loves 80's/90's style designs, though his are more in the pop-fashion that SciFi, he does love everything from that decade genre.
  20. Out of curiosity, for file/image fields, are the copied values going to point to the originating pagefile URL, or is it creating a completely new physical copy of the source items on the page where the repeater is pasted?
  21. Wow. That's embarrassing. You are 100% correct. ?‍♂️ Can't believe I didn't notice that after staring at it over multiple days. Thank you!!
  22. After your suggestion (thank you!) I did try the <!--PW-REGION-DEBUG--> tool from the primary template file (auto-append from site config), but unfortunately that seemed to render exactly what was expected: the one switch that was made indeed got switched. I made one error in my description of this problem, however: A die() statement inside the IF statement of the policy.php file does not render the content. The content is rendered if a die() statement is made within the callout.php field template, however.
  23. I'm having a strange issue that hopefully some more seasoned PW users would have some insight on. I have enabled the Functions API, Markup Regions, and am appending a primary template file (of which I currently only have one markup region defined). All secondary major page template files insert their content into that markup region. In one particular page template file, I am attempting to render a field template ("callout.php") if it has content. For whatever reason, it is not rendering. If I insert a <?php die(); ?> within the field template, the output from the template is visible. If I move that <?php die(); ?> statement to outside the IF/ELSE block that tests whether the field has a value, the content from the field's template is no longer rendered. Oddly enough, the RepeaterMatrix field's template immediately preceeding this particular field's template is rendered. Within /site/templates/policy.php, the following excerpt (for the callout field) is the troublesome code. <?php namespace Processwire; ?> [...] <section class="main-content" id="content-skip"> <h1><?= page()->title; ?></h1> <span class="policy-status">Last updated: Month, Year</span> <section class="policy-document"> <?= page()->render('content_body'); ?> </section> <?php if (page()->callout) { page()->render('callout'); } ?> </section> Within /site/templates/fields/callout.php I have the following: <?php namespace Processwire; ?> <div class="card border-<?= $value->callout_type->value; ?> mb-3 card-note"> <div class="card-header"></div> <div class="card-body"> <div class="card-text"><?= $value->content; ?></div> </div> </div> Regardless of whether the variables are correct or not (based on the die() statements, they are), I would expect the HTML to be rendered. Like stated, if I place a <?php die(); ?> statement inside (at the end) of the callout.php template file, I can see the expected PHP/HTML get output. If I instead place it after the IF statement in the policy.php template file, the HTML output from the callout.php file does not exist. I'm not sure if it's my mixing of output methods during implementation, or something else entirely. I tried passing an $options array value to prevent caching through page()->render('callout', ['allowCache' => false]); to see if it would make a difference. It did not.
  24. Hi Ben, This took me a bit to understand, but I think you're looking to generate an OpenGraph image similar to how GitHub's OG images appear to almost be an HTML page converted to an image? (At first I thought you just wanted to use a template to assign a specific page image and generate the meta text...) Chris Coyier at CSS-Tricks wrote up an overview of a couple different ways to produce something like this. His platform is WordPress using GD, but it could just as easily be applied to ProcessWire and IMagick. There are also services out there to help with this as well. See the comments for even more info. https://css-tricks.com/auto-generated-social-media-images/ I'm in the middle of cleaning, patching/repairing walls, and repainting my guest room after a "friend" destroyed it on me, otherwise I'd offer to get a quick example going for you over the weekend. However, your needs are likely custom to your project and there are any number of various ways to produce this, so hopefully the overview linked will give you a good head start! ?
×
×
  • Create New...