Jump to content


  • Posts

  • Joined

  • Last visited

  • Days Won


Everything posted by schwarzdesign

  1. Thanks for featuring this site in ProcessWire Weekly #443! Small update, the English site and the news section have been finished and are online now. If you're interested in the migration history and the museum, you can check out the English site!
  2. We recently launched DOMiD Labs, a new microsite for our existing client DOMiD. We already built the main site for DOMiD in 2019, as shown in our previous post here and featured in ProcessWire Weekly #296. The new DOMiD Labs site belongs to a project to plan participative museum concepts for the upcoming migration museum in Cologne, Germany. Concept, design and implementation by schwarzdesign - web agency in Cologne, Germany. Featured in ProcessWire Weekly #433 We're using an in-house starter project to bootstrap new ProcessWire projects. This allows us to deliver smaller projects on a low budget while still providing an extensive, modular content system and to spend some time polishing the features our clients care about. Notable features of the site include: A modular content builder utilizing the excellent Repeater Matrix field. A blog area with a paginated news index page. Multi-language support (site available in English and German). Q&A sections using accordion elements. A contact form built with the Form Builder module. Fully configurable navigation and footer components. Custom translation management for interface translations. Learn more: domidlabs.de
  3. @benbyf We ran into an issue with image resizing not working correctly on PHP 8, in particular when using focus points: https://github.com/processwire/processwire-issues/issues/1351 I'd consider this a showstopper since image resizing is absolutely necessary for responsive images, and when we tested a site on PHP 8, focus points either didn't work at all or result in fatal exceptions altogether.
  4. Herzzentrum Bonn The Herzzentrum Bonn (Heart Center Bonn) is part of the University Hospital Bonn (UKB) and consists of the cardiology and heart chirurgy clinics. Goals for the website were a clear content structure, friendly and personal communication tailored to the different visitor groups and easier maintenance and content updates. Concept, design and implementation by schwarzdesign. www.herzzentrum-bonn.de You can read more about the challenges, concept and implementation of this project in the case study on our website (German only). Notable modules used ProFields (especially RepeaterMatrix) FormBuilder ProCache UniqueImageVariations WireMailSmtp ProcessCacheControl ProcessRedirects TracyDebugger Development insights One thing to note is the central management of staff members. To represent staff members as well as the hiarchies and different departments, we created a layered template structure: person – Represents a single person and has fields for name, title, position, portrait, contact info etc. hierarchy – Represents a hiarchy level or department in the organisational structure. Has person pages as children. people – This is a singleton template which displays all team members sorted by hierarchy level. Has hierarchy pages as children. The central staff database is also used to display people throughout the site – for example, the experts on angiology on the angiology page. Most of the editorial content is created through a RepeaterMatrix field with different section types. The section type for people contains a simple page reference field, allowing the editor to select the people to display in a given context while still being able to edit their contact info in a central place. Another interesting content type are the track records on the homepage. Those are implemented using CountUp.js and a custom IntersectionObserver script to trigger the animation as soon as the section comes into view. Finally, we built a very flexible grid section which uses CSS grid to display grids with variable contents and row/column spans (see an example here). Screenshots
  5. @Robin S Good idea, thanks! The only problem I have with that solution is that it's hardcoded and there's no indication on the backend about the modification. This makes it harder to change fields, dependencies etc later on and it might cause problems if someone works on the site who doesn't know about that hook. So while it will solve this problem well, I'm worried it will cause others down the line. Of course, the same thing can be said about my hook above which just disables the field ? Another thing is that I would like the fields to be visible, just not editable, like a readonly field. So removing them entirely is not an option in this case. Though I will consider this approach for similiar problems, so thanks!
  6. We're currently working on a few sites that have some users with very limited access; most importantly, some users can only edit their own profile and nothing else in the backend. We're using AdminThemeUiKit, so the CMS navbar only contains the site logo and the username for those users. The problem is that the crucial "View site" link that gets you back to the frontend is hidden in the dropdown behind the username. This isn't immediately obvious (and TBH it does feel out of place there, even when you know it's there). I'm looking for ways to make the "back to site" link more visible – and I also think this is worth a discussion for AdminThemeUiKit in general. Here's what I have considered: Ideally, clicking the logo would take you back to the frontend (currently, you just get a blank page with nothing but an 'edit profile' button). I checked the settings, but the Uikit theme only has options to open the site tree or open a side navigation. Maybe a new option to go back to the frontend could be added? Or maybe the method that gets the logo link should be made hookable, so I could retain the default behaviour for editors, but change the link for users with limited access. An additional link in the menu would also work. But the only way I can think of to add this would be a Process module that just redirects to the homepage. But that's a bit overcomplicated, and I would like to do this without the additional redirect. Of course, copying the theme and modifying it manually or inserting a prominent link with JavaScript would work, but both options are sort of hacky and require some upkeep. Is there a better way? Have you come across this problem yet, and how did you solve it? I'm looking forward to suggestions!
  7. I'm trying to disable a specific field only when it is displayed on a user's profile edit page. I have worked out the following solution, but it's shaky and I'm looking for a better approach: // disable the member type field when members edit their own profile wire()->addHookBefore('InputfieldPage::render', function (HookEvent $e) { $inputfield = $e->object; $field = $inputfield->hasField; $user = $inputfield->hasPage; $process = wire('process'); // only handle the u_type field if ($field->name !== 'u_type') return; // only for profile edits if (!($process instanceof ProcessProfile)) return; // only for regular members without additional access if ($user->isSuperuser() || $user->hasRole('editor')) return; // get the inputfield the InputfieldPage is delegated to (InputfieldRadios) $delegatedInputfield = $inputfield->getInputfield(); // get all available options $optionKeys = array_keys($inputfield->getInputfield()->getOptions()); // build an array with option id => attributes maps (this is the format expected by InputfieldRadios) $optionAttributes = array_combine( $optionKeys, array_map(fn($o) => ['disabled' => 'disabled'], $optionKeys) ); // add the attributes to the delegated inputfield to disable all options $delegatedInputfield->addOptionAttributes($optionAttributes); }); What bugs me about this: Seems overly complicated, isn't there a better way than going through the delegated inputfield and then setting the attribute manually for all options? Like a global disabled switch on InputfieldPage? The hook is dependent on the type of delegated inputfield and might break if it's switched to something else. This only sets the HTML disabled attribute, so it's easy to bypass. Of course I could add backend validation separately, but I would prefer a "unified" solution. Though for my use-case the backend validation is not that important, it's more about UX. By the way, just setting the field to hidden does not work in this case, because a couple of other fields have show_if dependencies on the field I'm trying to disable, and those don't seem to work when the field is not rendered at all. Any of you know a better approach? Thanks!
  8. @d'Hinnisdaël Thanks for the reply! I've opened issue #1322 regarding the context-dependence of $user->editable. Hopefully something will come of it. I also found issue #538, which seems to be related to this? Not sure. Regardless, the fact that $user->editable returns different results based on context is troublesome in any case, so I think you're right that this should be fixed in the core.
  9. @d'Hinnisdaël I'm having some trouble with a Collection panel that lists user accounts. Specifically, with the "edit" action, which appears disabled for everyone but superusers. I checked the source code, apparently the edit action is disabled on DashboardPanelCollection.module#L327. $page->editable apparently returns false if the $page is a user, even for users with the user-admin permission. Probably because editing users is a special case? Anyway, changing this to a hardcoded false fixes the problem in my case. Of course this isn't a general solution. Maybe the module could check for this special case and only disable the edit action if the current user doesn't have the user-admin permission? Not sure what the best solution is, does anybody know why $user->editable returns false even if the current user has the user-admin permission? Thanks!
  10. @bernhard Can you use $modules->getModule() with the noPermissionCheck option? I haven't tried it yet, but according to the documentation it should bypass permission checks. We had a similar problem with a script that updates the database dump included in the site profile for our base installation. I solved it in the same way as you, by manually setting the current user to the superuser: use Composer\Script\Event; use ProcessWire\ProcessExportProfile; use function \ProcessWire\wire; use function \ProcessWire\fuel; class SchwarzdesignDevTools { /** @var string The path of the webroot. */ public const PUBLIC_WEBROOT_DIR = __DIR__ . '/../../../public/'; /** @var string The name of the site profile. */ public const SITE_PROFILE_NAME = 'site-schwarzdesign'; /** * Script to update the database dump included in the schwarzdesign site profile. * * @param Event|null $event * @return void */ public static function createDatabaseDump(?Event $event = null): void { // bootstrap processwire require_once self::PUBLIC_WEBROOT_DIR . 'index.php'; // set the "current user" to the superuser to enable access to the site profile export module $users = wire('users'); $superuser = $users->get(wire('config')->superUserPageID); $users->setCurrentUser($superuser); // initialize the profile exporter $processExportProfile = wire('modules')->get('ProcessExportProfile'); // dump the database into the site profile $path = self::PUBLIC_WEBROOT_DIR . self::SITE_PROFILE_NAME . '/install/'; $processExportProfile->mysqldump($path); $realpath = \realpath($path); echo "Database successfully dumped to {$realpath}/install.sql!" . \PHP_EOL; } }
  11. Just an update in case anyone is looking for this, setting arbitrary 3XX response codes is now possible! As of ProcessWire 3.0.166, $session->redirect now accepts an integer as the second argument, which may be any HTTP response code in the 3XX-range. The blog post above doesn't really mention this, but you can see the change in this commit. Thanks @ryan!
  12. Time for another small update! The Architekturführer Köln is now available in the Google Play Store. One of the major problems with the Progressive Web App approach was that people don't really know about it, and they're disappointed when they don't find it in the App Store / Play Store. The new Trusted Web Activities help solve this problem. We used bubblewrap to generate an app package based on the PWA that can be distributed through the Play Store. As a result, you can now find the Architekturführer in the Play Store! Takeaways: The app is really nothing more than a tiny website launcher that opens a Chrome instance without any UI. For the end user, it's barely distinguishable from the PWA when added to the home screen. But being available in the Play Store does help with visibility (and talking to clients). The Play Store requires a lot of info, screenshots in specific formats and buttons to be clicked before publishing an app there. Also, every change needs to be manually approved, so it takes a while. Don't start the process the evening before. I used appstorescreenshot.com to generate nice looking annotated screenshots for the Play Store page. Trusted Web Activities don't exist on iOS, so for now this only works for Android, not in the App Store.
  13. @ryan In the spirit of closing up Github issues, could you take a look at issue #1133? Changing passwords on the profile page does not work if the old password is pasted instead of typed in manually. Edge-case, admittedly, but when a client stumbles upon this it's pretty disruptive. As far as I can tell it's just a jQuery event that needs to listen to paste events as well as input events, so it should be a one-line fix. Though of course I don't know the code base so well, so I might be mistaken ? Same for issue #1111 about titles getting cut off in the page tree. Thanks!
  14. @Sergio Thanks! We suggested ProcessWire to the client, they were very happy with it ? Though they mostly interact with custom interfaces. Thanks for the report! I checked on a Windows 10 device but can't replicate the rendering issue. The site uses Rubik, though locally installed versions of the font take precedence. Maybe you have an older version of the font installed on your Computer? I know there were a couple of issues with older versions of Rubik ...
  15. We relaunched the website of German health insurance broker KLforExpats, who provide a service that is specifically tailored for expatriates in Germany. The website includes very extensive, completely custom-built forms for data entry and multiple custom interfaces for management and handling of requests. Concept, design, branding and development by schwarzdesign. If you are moving to Germany and need health insurance, KLforExpats is the contact for you! Read on below for some technical insights. Features A beautful, streamlined website including an extensive knowledge area (Expert Corner) Custom-built forms for initial contact and data collection A central database of clients / leads An analytics dashboard that displays key performance indicators based on the lead database A client / lead template with multiple workflow-related actions Automatic generation of Trello cards for new leads using the Trello API Notable modules Dashboard TrelloWire ProFields Hanna Code ListerPro Cacheable Placeholders Cache Control Automatically link page titles Unique Image Variations Regular shoutout to Tracy Debugger Building custom forms based on ProcessWire fields The forms on the site are built from scratch, which is a lot of work but opens up a lot of fine-tuning that isn't possible with form builder modules or services. There are a couple of interesting features of the form system we built. In particular, using built-in HTML5 features for form input and constraint validation makes developing simple, cross-browser and mobile-friendly forms a breeze. The forms make heavy use of modern input types and attributes. In particular, all date fields use the date input type, which is supported in all major browsers except Safari. This way, the forms come with good accessibility out of the box. A cleaner solution than using some rickety jQuery UI datepicker. Client-side validation is pure HTML5 as well. Since each form consists of multiple steps, the validation is triggered when the user tries to go to the next step. This is easily done by iterating through the inputs in the current step and calling reportValidity on them. The browser takes care of reporting errors – no need for a popup library. We use ProcessWire's field settings to generate field labels and validation attributes (like the required flag, minimum and maximum length settings etc.). This way, changes to the fields are always kept in sync between the frontend and the backend. For server-side validation, we used an open source library (rakit/validation). We added some custom rules to integrate it with ProcessWire's CSRF protection, a honeypot spam protection, and file uploads using WireUpload. This way, validation and error reporting can be done through a uniform interface. Using custom page classes as data models New leads are represented by ProcessWire pages. We ended up writing a lot of custom functionality for those pages – for example, automatically generating a vCard based on the contact information entered in the form. We used a custom page class as a nice way to group those methods and be able to call them from anywhere. <?php namespace schwarzdesign\Page; use Processwire\Page; class ClientPage extends Page { /*** methods here */ } Since each lead is a regular page, we used the regular page template to display all the data collected for this lead as well as to provide an interface to perform lead-related actions, like create form access keys, generate PDF protocols, etc. Since we use Twig as a templating layer, we ended up with a MVC-like approach, where the PHP-template is only used to call the appropriate methods of the ClientPage based on URL parameters. You can read more on the process and the client-facing functionality on the KLforExpats project showcase on our website (in German).
  16. @Robin S Oh I see, sorry I misread your reply the first time ? Enabling the textformatter is not an option for me because of the interferance with Twig. By the way I did consider turning Twig's autoescaping off and using textformatters instead, but in the end it's much easier to have Twig handle it instead of having to add the textformatter to every single field. So I'd say the issue is still valid, since there are use-cases for not wanting to use the formatter, even if they are not that common. Thanks for the workaround! I'll give that a try as well, either that or just use the proper smaller-than sign as suggested above ?
  17. @Jan Romero Thanks for the suggestion, I'll probably do that ^^ @Robin S Hm, curious. I have the HTML Entity Encoder turned off (because that is handled by Twig in our setup), but I'm still getting the cut-off title. I'm surprised you're getting different results. Not sure if this can be related to the textformatter, as the encoding is hard-coded inside ProcessPageListRender::___getPageLabel ...
  18. @ryan Can you take a look at the issue? This bug is causing some issues with one of our projects, and it should be a 5 minute fix ...
  19. @Robin S Alright I'll try this, thanks!
  20. Hi @Robin S, how do you feel about adding integer fields to the dialog? I have some fields that would benefit from allowing numbers only. I have tested adding the InputfieldInteger with inputType 'number' (for HTML5 support) and it works well: // iframe_form.php $type = 'InputfieldText'; if(isset($types[$key])) { switch($types[$key]) { /** ... */ case 'integer': $type = 'InputfieldInteger'; break; } } $f = $this->modules->get($type); if ($type == 'InputfieldInteger') { $f->inputType = 'number'; } Would you consider adding something like this to the module?
  21. We recently relaunched the website of IBIS Backwaren, a brand for international pastries and bakery products. Concept, design and implementation by schwarzdesign, built with ProcessWire. As always, we aimed to deliver a clean website design with a focus on content and fast loading times. Here's a list of modules used on this site, followed by a couple of interesting features included. The site is bilingual, though currently only the German version is available. The English version will be released at a later date. ProFields FormBuilder WireMailSMTP Cache Control MarkupSitemap Hanna Code Automatically link page titles Unique image variations Product database and product collections The website features a product database with all the products IBIS distributes. The product template is rather extensive, including fields for product categories and attributes, nutrition facts, certifications etc. We make heavy use of page reference fields, e.g. for product categories and attributes such as vegan or gluten-free products. Nutrition facts are stored in a Textareas field. There are multiple ways for visitors to explore products. One is a classic product finder with filters for product category and attributes. But there are also individual product collections (Produktwelten) which can be regularly updated by the client. Product collections include a list of related products. This allows the marketing department to quickly set up targeted landing pages. Recipes and custom forms Another approach to marketing and activating fans is the recipe section. Each recipe uses at least one IBIS product to give visitors some ideas. Of course, recipes and products are cross-linked to allow for exploration and discovery. There's a recipe submission form which allows you visitors to send in their own recipes, as well as a couple of other forms. All forms on the site are built with the Form Builder module. We made use of the form submissions to pages feature, which automatically creates a new (unpublished) page for new recipe submissions. Those can be reviewed by the staff and published directly. We also use a hook to automatically transform the plaintext fields for ingredients and instructions into HTML lists. Multi-brand IBIS uses different brands for different sets of products. Some landing pages as well as the gluten-free selection are branded differently. To accomodate this, we create an additional "brand" template with an override for the default logo. Each page has a brand selection field to allow switching the logo / branding for that page. Since brands are represented by normal pages, then client can create additional brands on their own.
  22. Thanks for your help @Robin S!
  23. Hi @Robin S, I have tested a couple more scenarios, I believe the missing dropdown has something to do with the dynamic AJAX-loading of repeater matrix items. If I set "Repeater dynamic loading (AJAX) in editor" to "New items only", the Hanna Dialog appears on all existing repeater items. Though if I then add a new repeater matrix item of a type that's not used on this page yet, the Hanna Dialog is missing. Once I save the page and the new item is loaded through the normal page visit, the Hanna Dialog shows up. So probably the hook that adds the JS settings just doesn't fire for AJAX-loaded items? To test this, I've put a bd($key) statement on this line where the extraPlugins config is added. When dynamic loading for my repeater field is set to "New items only", it shows all CK Editor fields, even those inside the repeater matrix: But if I activate AJAX-loading for all repeater items, the matrix CK Editor inputfields don't show up: --- So, disabling AJAX mostly fixes the problem, though the dialog is missing form newly added repeater matrix items before the page is saved. Do you think it's possible to make this work with AJAX-loaded repeater matrix items as well? Thanks for your help! --- EDIT: Another thing I found: It's working fine when I disable all local field overrides for the CK Editor field (it's set to required in the Repeater Matrix context). So probably if there are no overrides the Matrix just uses the config of the normal "InputfieldCKEditor_html_basic", which includes the HannaDialog, but if there ARE overrides it generates the "InputfieldCKEditor_html_basic_matrix1" configs which DON'T include the HannaDialog plugin because they're loaded through AJAX. Does that make sense?
  24. @Robin S Yes, that's the version I'm using. Hm, curious. Though that's not the first issue I have with CK Editor fields inside RepeaterMatrix fields (see the thread you linked above as an example). I'm wondering if there's something wrong with my ProcessWire installation or something. I'll investigate further next week!
  25. Thanks for the follow-up @Robin S. The toolbar settings are correct – the same field is displaying the toolbar item fine when it's not inside the RepeaterMatrix field. Which version of RepeaterMatrix have you tested this with? I'm using the current v5-dev Version. I just switched to RepeaterMatrix v4 as a test, with this version it's working correctly. Can you check if you're getting the same problem in the v5-dev version? Thanks!
  • Create New...