Jump to content

dragan

Members
  • Posts

    2,007
  • Joined

  • Last visited

  • Days Won

    21

Everything posted by dragan

  1. So... it seems my SQL is a bit rusty. I fired up ChatGPT, entered my question, along with the mySQL export of all relevant tables (incl. content), and hey: Got a working query back in no time, with nice explanations.
  2. Nice site, congrats! Tip for everyone outside the US: Try visiting with the Tor browser. I could access it without problems from Switzerland. re: forms I can highly recommend the Pro module FormBuilder from Ryan. Well worth the money.
  3. Same here. I've been tinkering with SSE on and off, and that one-liner made the crucial difference.
  4. That site was made with Shopify. Why not choosing the same platform? Why do you want to reinvent the wheel, and then also on a low budget? Makes no sense whatsoever.
  5. On a sidenote: htmx is getting more and more attention. Recent example: It was the spotlight teaser of the last JavaScript Weekly newsletter.
  6. Is https://path.to.API.endpoint another PW instance? Or completely unrelated to your PW site? I would first try the basics: Make a manual request with something like Postman and see if it works at all. Delete all your cookies from the API endpoint domain. The response from the developer is somewhat confusing, and doesn't make sense. If you can't even get a response from the API due to a server error 400, you also can't deliver a PDF.
  7. Well, you can change the CSS for small screens of course. Have you thought about choosing another time format, i.e. omit the timezone? Can't you output the timezone in a separate row? The only other idea I would try is to insert spans and only wrap numbers in a css class that has tabular-nums
  8. Well, I meant if you have ProDrafts installed, but it would be missing the batch publishing feature. I know that building a staging workflow from scratch is far from easy - otherwise we'd have a dozen modules out there already and this forum thread wouldn't even exist 🙂
  9. I have never used ProDrafts, but the docs mention a drafts manager: https://processwire.com/store/pro-drafts/#drafts-manager Sounds like it's exactly what you're asking for. And even if that feature wouldn't exist: It would be quite easy to use ListerPro and write a custom Batch Action I guess...
  10. Try white-space: nowrap; Or if it's a table: table-layout: fixed;
  11. Good work, @bernhard! Reading those links linked above made me smile... especially the pig-with-wings vs. panther analogy from Ryan 🙂 "but we don't want a pig, we want a panther" - someone pls make a meme anim. GIF, or a T-Shirt please 🙂
  12. Check if you have the same "advanced" settings in both sites: $config->advanced = true; Can you open page id 3 (that's Admin > Pages) directly? https://mysite.com/admin/page/edit/?id=3 What do you see in the settings tab? It should look like this, if you have advanced mode activated: Normally, you shouldn't have to play around with these settings on a default admin (system) page. Also... seems obvious to check first, but perhaps you have some hooks or your own custom module installed that interferes with normal behavior?
  13. We're looking for someone to take over a ProcessWire site. I will leave the agency I'm currently working for, and since I was the only PW-developer there, we can't guarantee a professional maintenance anymore. Some information: Site is multilingual, 4 languages Pro modules: FormBuilder, Lister and ProFields Current version is 3.0.210 and was launched 5 years ago. The site makes heavy use of FormBuilder. The data is saved to Google Sheet. That works smooth as silk, but sometimes the client needs a helping hand with config (basically, there is a master form which they always clone, and then change some basic stuff). This Google Sheet has to be moved to another account. There is nothing overly complex about this site. There are a few protected pages. I have written a big manual for the client, i.e. tips about the WYSIWYG editor, recommended image sizes, FormBuilder gotchas, how and where to edit categories (related pages) etc. To be honest, I don't expect a big number of new feature requests in the near-term future. We just want to make sure they know who to call, if there's any questions. However, they mentioned that they want a rehaul of the homepage (they switched hosting recently and bought a new domain). If you're interested, write me a PM.
  14. Sometimes it can help if you choose another syntax, i.e. pages()->find() or \ProcessWire\wire - depending on whether you're editing a template or module. Give it a try. There's also this:
  15. Yes! Seriously, someone pls email @ryan about this. If no one else will do it, I'll do it. My new favorite ProcessWire infographic:
  16. @wbmnfktr I agree. If you're busy publishing stuff (your own blog, medium.com or elsewhere), you might want to add your latest articles to the sig. Ditto if you hold events of some sorts (webcasts, seminars) - it doesn't hurt to advertise them in your mail footer. Just don't go crazy with imagery/styling - you don't want the sig to attract more attention than the actual mail message 🙂
  17. What's the big picture here? Will this div-soup eventually contain content? Or stay like that, just as some sort of decoration? The easiest way to do what you want, is using a plain old table - but with role=presentation. If you don't present tabular data to the user, this is OK. <table role="presentation"> <tr> <td></td> <td></td> <td></td> </tr> <tr> <td></td> <td></td> <td></td> </tr> <tr> <td></td> <td></td> </tr> </table> table { border-collapse: collapse; width: 150px; } td { width: 50px; height: 50px; border: 1px solid black; } https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Roles/presentation_role
  18. I guess this should do the trick (delete orphaned images) // before the function definition: $imageFields = array(); // hold all image field-names // replace/insert in my above function this: // tell PW that all the data needs to be saved foreach ($copy->fieldgroup as $field) { if ($field->type !== "FieldtypeImage") { if ($copy->hasField($field)) $copy->trackChange($field->name); } else { $imageFields[] = $field->name; // here } } // test it: $pg = $pages->get(23506); // clone a page $newClone = cloneWithoutFiles($pg); $id = $newClone->id; // echo "new page id = $id <br>"; $pg = $pages->get($id); $pg->of(false); foreach($imageFields as $f) { $pg->$f->deleteAll(); $pg->save($f); } Perhaps there's a cleaner way to do all this... it would be nice to have this as an option built into the core function!
  19. Basically, you could clone the clone function (ha!) from the core and alter it slightly: https://github.com/ryancramerdesign/ProcessWire/blob/master/wire/core/Pages.php#L1733 function cloneWithoutFiles(Page $page, Page $parent = null, $recursive = true, $options = array()) { $defaults = array( 'forceID' => 0, 'set' => array(), 'recursionLevel' => 0, // recursion level (internal use only) ); if (is_string($options)) $options = Selectors::keyValueStringToArray($options); $options = array_merge($defaults, $options); if ($parent === null) $parent = $page->parent; if (count($options['set']) && !empty($options['set']['name'])) { $name = $options['set']['name']; } else { $name = wire()->pages->names()->uniquePageName(array( 'name' => $page->name, 'parent' => $parent )); } $of = $page->of(); $page->of(false); // Ensure all data is loaded for the page foreach ($page->fieldgroup as $field) { // changed: if ($field->type !== "FieldtypeImage") { if ($page->hasField($field->name)) $page->get($field->name); } } /** @var User $user */ $user = wire()->wire('user'); // clone in memory $copy = clone $page; $copy->setIsNew(true); $copy->of(false); $copy->setQuietly('_cloning', $page); $copy->setQuietly('id', $options['forceID'] > 1 ? (int)$options['forceID'] : 0); $copy->setQuietly('numChildren', 0); $copy->setQuietly('created', time()); $copy->setQuietly('modified', time()); $copy->name = $name; $copy->parent = $parent; if (!isset($options['quiet']) || $options['quiet']) { $options['quiet'] = true; $copy->setQuietly('created_users_id', $user->id); $copy->setQuietly('modified_users_id', $user->id); } // set any properties indicated in options if (count($options['set'])) { foreach ($options['set'] as $key => $value) { $copy->set($key, $value); // quiet option required for setting modified time or user if ($key === 'modified' || $key === 'modified_users_id') $options['quiet'] = true; } } // tell PW that all the data needs to be saved foreach ($copy->fieldgroup as $field) { // changed: if ($field->type !== "FieldtypeImage") { if ($copy->hasField($field)) $copy->trackChange($field->name); } } wire()->pages->cloneReady($page, $copy); wire()->cloning++; $options['ignoreFamily'] = true; // skip family checks during clone try { wire()->pages->save($copy, $options); } catch (\Exception $e) { wire()->cloning--; $copy->setQuietly('_cloning', null); $page->of($of); throw $e; } wire()->cloning--; // check to make sure the clone has worked so far if (!$copy->id || $copy->id == $page->id) { $copy->setQuietly('_cloning', null); $page->of($of); return wire()->pages->newNullPage(); } // copy $page's files over to new page // changed: // basically, you could delete this block altogether if (PagefilesManager::hasFiles($page)) { // $copy->filesManager->init($copy); // $page->filesManager->copyFiles($copy->filesManager->path()); } // if there are children, then recursively clone them too if ($page->numChildren && $recursive) { $start = 0; $limit = 200; $numChildrenCopied = 0; do { $children = $page->children("include=all, start=$start, limit=$limit"); $numChildren = $children->count(); foreach ($children as $child) { /** @var Page $child */ $childCopy = wire()->pages->clone($child, $copy, true, array( 'recursionLevel' => $options['recursionLevel'] + 1, )); if ($childCopy->id) $numChildrenCopied++; } $start += $limit; wire()->pages->uncacheAll(); } while ($numChildren); $copy->setQuietly('numChildren', $numChildrenCopied); } $copy->parentPrevious = null; $copy->setQuietly('_cloning', null); if ($options['recursionLevel'] === 0) { // update pages_parents table, only when at recursionLevel 0 since parents()->rebuild() already descends if ($copy->numChildren) { $copy->setIsNew(true); wire()->pages->parents()->rebuild($copy); $copy->setIsNew(false); } // update sort if ($copy->parent()->sortfield() == 'sort') { wire()->sortPage($copy, $copy->sort, true); } } $copy->of($of); $page->of($of); $page->meta()->copyTo($copy->id); $copy->resetTrackChanges(); wire()->pages->cloned($page, $copy); wire()->pages->debugLog('clone', "page=$page, parent=$parent", $copy); return $copy; } // basic usage just as with original function: $pg = $pages->get(23506); cloneWithoutFiles($pg); Besides the three places marked with // changed, I also had to replace $this-> with wire()-> to use it in a template file. Images (files) are not copied to the new page, however, the fields are. It wouldn't be too hard to delete these after you've created the clone (after initial clone-save).
  20. @Carsten The echo '<pre>' part comes too early. Change the first few lines to: <?php namespace Processwire; ini_set('max_execution_time', 60 * 5); // 5 minutes, increase as needed include("./index.php"); echo '<pre>'; // rest below unchanged: // Add a leading back slash to the class so it can access the global namespace $dir = new \DirectoryIterator(wire('config')->paths->files); Tried the script like this and it works just fine (PW 3.0.205)
  21. That's weird. Laragon keeps working fine for me, with several PHP versions, one of them being 8.1.8. There are far better tools than phpMyAdmin. Try HeidiSQL.
  22. @ryanThis looks awesome! At first glance, the only thing missing for me is VAT. Do you plan to add that later? If not, how easy would it be to add this?
  23. PHP? Really? All you basically need is some admin CSS. #PageEditTabs { position: fixed; top: 261px; left: 0; flex-direction: column; } ^ this surely doesn't look fancy, but it could serve as a starting point...
  24. You're welcome ? Your current implementation of your DL has display: none on the entire definition list (inline styles). I understand this is work in progress, but display: none will be completely ignored by screen readers. I would put the class .sr-only not just on the h2, but on the entire section instead. I just now, on second sight, realized that unter "map options" you have a lot more stuff going on, in an accordion, with all kinds of filters. Previously I just looked at the first accordion item "library floor". As you have correctly mentioned, complex visuals that convey information, need special attention re: a11y. There are no quick shortcuts or golden recipes that help you out. It's all about context. You have put a tremendous amount of work into exploring the building, making sure the user can filter / find everything. This whole "map options" thing is sure a great help for "regular" users who are not visually impaired. Kudos to that. Now, if you look at the big picture, you will realize that all these fine-grained options don't do anything for the non-visual users. They will most likely be confused. If you wanted to build the entire filter/options functionality with a11y in mind, you would need to invest a lot of work. You'd have to use aria-live to inform the user that something has changed in the map after the user made a new selection. Currently, if the user selects the "Glasby Room" radio button, the visually impaired persons don't get the information that regular users get (by toggling/removing the inline display:none). You would have to map these with either an aria-label right at the input level, or with aria-describedby or some such. (I strongly encourage you to test it out yourself with a screen reader - don't rely on automated tests like Lighthouse - they all have their limits, especially when it comes to context) I would personally visually hide all filter stuff under "map options", but provide a table in each accordion item. Tables are well-supported by assistive technologies, while DLs are only so-so. If budget is tight (and it always is tight for accessibility-related work) I'd opt for one big .sr-only table, and use aria-hidden on both the SVG and the filters. Just my 0.02.
×
×
  • Create New...