Jump to content

Stefanowitsch

Members
  • Posts

    345
  • Joined

  • Last visited

  • Days Won

    5

Stefanowitsch last won the day on September 13 2023

Stefanowitsch had the most liked content!

Contact Methods

  • Website URL
    https://www.thumann-media.de

Profile Information

  • Gender
    Male
  • Location
    Germany
  • Interests
    Web Design, Web Development, Music

Recent Profile Visitors

The recent visitors block is disabled and is not being shown to other users.

Stefanowitsch's Achievements

Sr. Member

Sr. Member (5/6)

319

Reputation

  1. A nice weekend to everyone! It’s bin a while since I posted a decent showcase of one of my projects but I’ve been rather busy with other things (as ProcessWire development is not my main job). I’ve noticed that the showcases that are posted here are featuring sites that are really stunning. The ProcessWire community is producing better and better results as it seems. Really hard for me to catch up 🙂 Anyway I want to share a really interesting project: The Relaunch of the community portal for the district “Barmbek Nord” of the city of Hamburg, germany. This showcase is quite large because of all the technical concept description and markup details. If you want a quick look how the editing of the page looks like I included a video demonstration right here: Bildschirmaufnahme 2025-01-18 um 14.22.27.mp4 To keep it brief here is what this community portal is all about: The website Barmbek-Nord.info is a community portal for the Barmbek-Nord neighborhood in Hamburg, Germany. It features local events, cultural activities, initiatives, and resources, such as volunteer opportunities, social projects, and a calendar of events. It also highlights neighborhood news, collaboration opportunities, and community meetings to enhance the area's quality of life. This project was a collaboration of three parties: 1. the district council (providing the future page structure, contents and design ideas) 2. a web designer (https://www.andre-kraemer.de/) 3. me as the developer (https://www.thumann-media.de/) 1. Redesign Concepts Here is a picture of the old website (based on Word Press). This of course was a bit outdated (design wise) at the end of its lifecycle. The district Barmbek-Nord presents itself as a vibrant, exciting and diverse part of Hamburg and this version of the website was not representative at all. Luckily the district council hat a pretty clear vision of what the new version should look like. Basically it was all about “boxes and shapes”. So this was the final design concept hat I took as a blueprint for developing the page: 2. Layout anatomy If you are living in Germany you know the famous chocolate brand “Ritter Sport”. They have an even more famous slogan it’s called “Quadratisch. Praktisch. Gut.” which would translate to “Square. Practical. Good.” So you can describe the whole design concept with these three words 😉 There are two main page templates: Tile Page A Tile Page is divided into multiple grid boxes. There are 8 different grid box layouts available which can be placed in any order. Each grid box is horizontal and has the same dimensions but is divided into subboxes. Subox dimensions vary: There are squares, and rectangles in different alignments and in different amounts. Each of those “sub boxes” inside the grid can hold a specific design element. These design Elements include for example - Plain Images - Textfields - Speech Bubbles - Image and Text combined - and so on Everything is handled with the RockPageBuilder (more about that in the next points) Content Page As the name suggests, a Content Page is used for text-heavy pages. This page template does not feature any box grid layouts. Instead the page structure is predefined: 1. Header area with headline and image fields 2. Content area 3. Content area with specific content blocks that can be chosen using the RockPageBuilder. 3. Technical difficulties The four main challenges when developing the page were: 1. Creating Pages based on multiple stacked grid box layouts 2. Offer individual content elements for each of the grid boxes subboxes 3. The Boxes all have a fixed aspect ratio and should retain it on desktop and mobile devices 4. Make everything user friendly to edit (!) I made a small proof of concept using the RockPageBuilder and it worked out of the box! Let me explain: Here is what the 8 different grid box layouts look like: 4. Technical solutions How do you handle nested content blocks in the RockPageBuilder? Well this is no problem at all and actually quite straight forward. Step 1: Create a RPB Field for the main grid layout blocks and add it to your template Step 2: Create a new Block Type for each of the individual grid box layouts for this field: Now you can add multiple grid layouts to your page templates. But not without some markup of course. The markup of a grid box looks like this: <?php namespace ProcessWire; use RockPageBuilderBlock\LayoutA; /** @var Page $page */ /** @var LayoutA $block */ ?> <section class="rpb-layouta" <?= alfred($block,["trash" => false, "clone" => false, "widgetable" => false])?>> <div id="div1" class="col-2x1"><?= $block->rpb_cell_2_1_a->render(true); ?></div> <div id="div2" class="col-1x1"><?= $block->rpb_cell_1_1_a->render(true); ?></div> <div id="div3" class="col-1x1"><?= $block->rpb_cell_1_1_b->render(true); ?></div> <div id="div4" class="col-2x2"><?= $block->rpb_cell_2_2_a->render(true); ?></div> </section> As you can see you have to create individual RockPageBuilder fields for each sub box and and include them into the markup! Based on the design concept we have four different sub box aspect ratios (width/height) 1x1, 1x2, 2x1, 2x2 There can be two sub boxes with the same aspect ratio in one grid layout, so it was necessary to create two variants (named with the suffix “a” and “b”) of the same RPB field. The CSS for a layout box looks like this. I make massive use of the “grid layout” feature as this offers me an relative easy way to control the layout as well as keeping the aspect ratio. .rpb-layouta { min-height: 50px; display: grid; grid-template-rows: repeat(2, 1fr); grid-template-columns: repeat(4, 25%); gap: 0; #div1 { grid-area: ~"1 / 1 / 2 / 3"; } #div2 { grid-area: ~"2 / 1 / 3 / 2"; } #div3 { grid-area: ~"2 / 2 / 3 / 3"; } #div4 { grid-area: ~"1 / 3 / 3 / 5"; } @media @max-m { grid-template-rows: repeat(4, 1fr); grid-template-columns: repeat(2, 50%); #div1 { grid-area: ~"1 / 1 / 2 / 3"; } #div2 { grid-area: ~"2 / 1 / 3 / 2"; } #div3 { grid-area: ~"2 / 2 / 3 / 3"; } #div4 { grid-area: ~"3 / 1 / 5 / 3"; } } } Step 3: Creating sub box content blocks for the nested RPB fields Now this was the main part of the work. Based on the design concept I had to create individual content elements for the sub boxes (all RockPageBuilder Blocks). All together with markup, styles and configuration options (!) As I mentioned before these content elements consist of: - Plain Images - Textfields - Speech Bubbles - Image and Text combined - and so on Let’s take this sub box content element as an example. It is called “Image Bubble Horizontal”: The markup of this Blocks view file looks like this: <?php namespace ProcessWire; use RockPageBuilderBlock\ImgBubbleHorizontal; /** @var Page $page */ /** @var ImgBubbleHorizontal $block */ ?> <?php $bubbleForm = $block->settings('bubbleForm'); $bubblePosition = $block->settings('bubblePosition'); $bubbleColor = $block->settings('bubbleColor'); $customColorBubble = $block->settings('customColorBubble'); if ($bubbleColor === 'custom') { $bubbleColor = $customColorBubble; } $linkColor = $block->settings('linkColor'); $customColorLink = $block->settings('customColorLink'); if ($linkColor === 'custom') { $linkColor = $customColorLink; } ?> <section class="rpb-imgbubblehorizontal uk-height-1-1 uk-position-relative" data-id="<?=$block->id;?>" <?= alfred($block,["addTop" => false,"addBottom" => false,"clone" => false]) ?>> <?php $image = $block->img_single; if ($image) { ?> <img srcset="<?= $image->size('horizontal')->srcset() ?>" src="data:image/svg+xml;charset=utf-8,%3Csvg xmlns%3D'http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg' viewBox%3D'0 0 <?=$config->imageSizes['horizontal']['width']?> <?=$config->imageSizes['horizontal']['height']?>'%2F%3E" sizes="auto" width="<?= $config->imageSizes['horizontal']['width']?>" height="<?= $config->imageSizes['horizontal']['height']?>" alt="<?= $image->description ?>" loading="lazy" /> <?php } ?> <div class="speech-bubble uk-flex uk-flex-center uk-flex-middle bubble-form-<?=$bubbleForm;?> <?=$bubblePosition;?>"> <div class="speech-bubble-content"> <?= $block->body(); ?> </div> <img style="color: <?=$bubbleColor?>;" src="/site/templates/images/bubbles/bubble-<?=$bubbleForm;?>.svg" uk-svg/> </div> <style> section[data-id="<?=$block->id?>"] a { color: <?=$linkColor?> !important; } </style> </section> I don’t want to go into details too much but one of the many great features of the RockPageBuilder module is that you can include and block specific setting fields directly into the Blocks PHP file without the hassle of creating those fields in the backend in the first place and adding them to the block manually. What a time saver this was! For example the content element “Image Bubble Horizontal” should have several config options. - the shape of the speech bubble - the position of the speech bubble - the color of the speech bubble - the color of the link text (if included) This is all done in the settingsTable method (https://www.baumrock.com/en/processwire/modules/rockpagebuilder/docs/settings/) public function settingsTable(\ProcessWire\RockFieldsField $field) { // You can set default settings for all blocks via hook. // See docs for details or leave this line unchanged. $settings = $this->getDefaultSettings($field); $settings->add([ 'name' => 'bubbleForm', 'label' => 'Sprechblase Form:', // the first parameter must match the name of the setting!! // in this case the setting's name is "demo", so we use "demo" here as well 'value' => $field->input( 'bubbleForm', // use either "radios" or "radios-inline" 'select', [ '*hexagon' => 'sechseckig', // the star marks the default option 'square' => 'viereckig', 'round' => 'rund', ] ), ]); $settings->add([ 'name' => 'bubblePosition', 'label' => 'Sprechblase Position:', 'value' => $field->input( 'bubblePosition', // use either "radios" or "radios-inline" 'select', [ 'uk-position-top-left' => 'Oben links', // the star marks the default option 'uk-position-top-center' => 'Oben mitte', 'uk-position-top-right' => 'Oben rechts', '*uk-position-center-left' => 'Mitte links', 'uk-position-center' => 'Mitte', 'uk-position-center-right' => 'Mitte rechts', 'uk-position-bottom-left' => 'Unten links', 'uk-position-bottom-center' => 'Unten mitte', 'uk-position-bottom-right' => 'Unten rechts', ] ), ]); $settings->add([ 'name' => 'bubbleColor', 'label' => 'Sprechblase Farbe:', 'value' => $field->input( 'bubbleColor', // use either "radios" or "radios-inline" 'select', [ '*#e61b7b' => 'Magenta', // the star marks the default option '#1cae8d' => 'Grün', '#dea500' => 'Gelb', '#646363' => 'Grau', 'custom' => 'Eigene Farbe', ] ), ]); $settings->add([ 'name' => 'customColorBubble', 'label' => 'Eigener Farbwert Sprechblase (HEX Code)', 'value' => $field->input('customColorBubble', 'text'), 'showIf' => 'bubbleColor=custom', ]); $settings->add([ 'name' => 'linkColor', 'label' => 'Linktext Farbe:', 'value' => $field->input( 'linkColor', // use either "radios" or "radios-inline" 'select', [ '*#e61b7b' => 'Magenta', // the star marks the default option '#1cae8d' => 'Grün', '#dea500' => 'Gelb', '#646363' => 'Grau', 'custom' => 'Eigene Farbe', ] ), ]); $settings->add([ 'name' => 'customColorLink', 'label' => 'Eigener Farbwert Linktext (HEX Code)', 'value' => $field->input('customColorLink', 'text'), 'showIf' => 'linkColor=custom', ]); return $settings; } The edit mask of the block then looks like this: 4. See it in action Heres a quick demonstration video of how the page editing with the layout bocks and nested blocks is working in real time: Bildschirmaufnahme 2025-01-18 um 14.22.27.mp4 5. Modules and other tech - UIkit 3 as frontend framework - RockFrontend (https://www.baumrock.com/processwire/module/rockfrontend/) - RockPageBuilder (and lots of thanks to @bernhard for helping me out on this project) (https://www.baumrock.com/processwire/module/rockpagebuilder/) - Cronjob Database Backup (https://processwire.com/modules/cronjob-database-backup/) - ProcessWire User Activity (https://processwire.com/store/pro-dev-tools/user-activity/
  2. @nbcommunication I recently updated on my site to make use of the new module version and it worked fine. Suddenly the feed is no longer displaying anything and I am getting this error message in the log files: Could not process user media: {"error":{"message":"Error validating access token: Session has expired on Saturday, 14-Dec-24 01:23:54 PST. The current time is Tuesday, 17-Dec-24 07:50:40 PST.","type":"OAuthException","code":190,"fbtrace_id":"ALq9x9hasK45lecwrhHmaep"}} I never faced this error before. I tried re-authorizing the account, generated a new token and placed it into the module settings but I keep getting this error message. EDIT: After a short period of time (i just checked again) the feed is working again. I don't know if re-authorizing was the solution but it seems that it worked in the end 🙂
  3. Hi @nbcommunication, I have a question about rendering the description text of an instagram post. Right now i am printing out the text via the description property like this: <?= $item->description ?> Unfortunately the text formatting gets lost. Here is what the post looks like on instagram: And this it how it looks like on my website: I understand that this is what the Instagram API returns, but is there really no way of getting a formatted text in return?
  4. I think this is a kind of special case. I don't know if all project that involve frontend editing (in combination with modal windows) do suffer from the same behaviour.
  5. Yes the problem seems to be related to the jQuery version I am adding manually in the header vs. the JqueryCore Version that is loaded in the PageFrontEdit.module file. The Alfred.js itself does not load any jQuery files (it just checks if there are any available). This is the solution that seems to work: 1. Load JqueryCore.js instead of any jQuery Version in the first place (do not use the 'defer' attribute here) ->add('/wire/modules/Jquery/JqueryCore/JqueryCore.js') 2. Disable the loading of JqueryCore.js in the PageFrontEdit.module on line 801: //'file' => $config->urls('JqueryCore') . ($config->debug === 'dev' ? 'dev/' : '') . 'JqueryCore.js',
  6. Hi @bernhard I updated a (not so old) project and I am using the following versions of modules - ProcessWire 3.0229 - RockFrontend 3.23.3 - RockPageBuilder 5.5.4 When loading a page in the frontend (when logged in) this error message is appears in the console: jquery-3.3.1.min.js?m=1531755686:2 Uncaught TypeError: Cannot read properties of undefined (reading 'dialog') at HTMLDocument.<anonymous> (<anonymous>:1:10079) at l (jquery-3.3.1.min.js?m=1531755686:2:29375) at c (jquery-3.3.1.min.js?m=1531755686:2:29677) When I want to open an alfred editor modal window via the "edit block" button, the modal window does not open. Instead I am redirected to the backend edit mask of the block page and this error pops up in the console: jquery-3.3.1.min.js?m=1531755686:2 Uncaught TypeError: r.getClientRects is not a function at w.fn.init.offset (/site/templates/scripts/jquery-3.3.1.min.js?m=1531755686:2:83688) at Object.getWithinInfo (/wire/modules/Jquery/JqueryUI/JqueryUI.js:6:14769) at e.fn.position (/wire/modules/Jquery/JqueryUI/JqueryUI.js:6:15042) at e.<computed>.<computed>._position (/wire/modules/Jquery/JqueryUI/JqueryUI.js:7:14716) at e.<computed>.<computed>.<anonymous> (/wire/modules/Jquery/JqueryUI/JqueryUI.js:6:5029) at e.<computed>.<computed>._position (/wire/modules/Jquery/JqueryUI/JqueryUI.js:6:5029) at e.<computed>.<computed>.open (/wire/modules/Jquery/JqueryUI/JqueryUI.js:7:6534) at e.<computed>.<computed>.<anonymous> (/wire/modules/Jquery/JqueryUI/JqueryUI.js:6:5029) at e.<computed>.<computed>.open (/wire/modules/Jquery/JqueryUI/JqueryUI.js:6:5029) at e.<computed>.<computed>._init (/wire/modules/Jquery/JqueryUI/JqueryUI.js:7:5169) This project uses by default jQuery 3.3.1. – I tried different jQuery versions but this error is always shown. Updating the jQueryUI version did not help either. In fact - what did help - was removing jQuery at all 🙂 but this is no solution of course. I am loading my scripts like this within the <head> markup: <? $scripts = $rockfrontend->scripts() ->add($config->urls->templates . 'scripts/jquery-3.3.1.min.js', "defer") ->add($config->urls->templates . 'scripts/lazysizes/lazysizes.min.js', "defer") ->add($config->urls->templates . 'scripts/aos/aos.js', "defer") ->add($config->urls->templates . 'scripts/bootstrap/util.js', "defer") ->add($config->urls->templates . 'scripts/bootstrap/carousel.js', "defer") ->add($config->urls->templates . 'scripts/bootstrap/collapse.js', "defer") ->add($config->urls->templates . 'scripts/owlcarousel/owl.carousel.min.js', "defer") ->add($config->urls->templates . 'scripts/lightbox/lightbox.js', "defer") ->add($config->urls->templates . 'scripts/main.js', "defer") ->minify(!$config->debug); ?> My question is: Does jQuery somehow collide with any of the sripts used to make the frontend editing and popups work? In all my newer projects I don't use jQuery at all so this never bothered me. This is one of my "legacy" websites however.
  7. Yes that seemed like a weird "hickup" in the log files. I never experienced this behaviour in any other project. But I am glad that it was an easy fix!
  8. Very interesting. The folder only contained only old logs: Logging the bd($entry) revealed an error from 2023 that was actually no longer part of the reay.php anymore. I manually deleted all tracy logs files inside the site/assets/logs/tracy folder and also deleted the cache folder under /assets. After that this error disappeared.
  9. I keep getting this error message on all backend and frontend pages in one of my projects: ErrorException: Undefined array key 1 in /var/www/html/site/assets/cache/FileCompiler/site/modules/TracyDebugger/panels/TracyLogsPanel.php:71 Stack trace: #0 /var/www/html/site/assets/cache/FileCompiler/site/modules/TracyDebugger/panels/TracyLogsPanel.php(71): Tracy\Bar->Tracy\{closure}(2, '...', '...', 71) #1 /var/www/html/site/assets/cache/FileCompiler/site/modules/TracyDebugger/tracy-2.10.x/src/Tracy/Bar/Bar.php(142): TracyLogsPanel->getTab() #2 /var/www/html/site/assets/cache/FileCompiler/site/modules/TracyDebugger/tracy-2.10.x/src/Tracy/Bar/Bar.php(115): Tracy\Bar->renderPanels('') #3 /var/www/html/site/assets/cache/FileCompiler/site/modules/TracyDebugger/tracy-2.10.x/src/Tracy/Bar/Bar.php(89): Tracy\Bar->renderPartial('...') #4 /var/www/html/site/modules/TracyDebugger/tracy-2.10.x/src/Tracy/Debugger/DevelopmentStrategy.php(123): Tracy\Bar->render(Object(Tracy\DeferredContent)) #5 /var/www/html/site/assets/cache/FileCompiler/site/modules/TracyDebugger/tracy-2.10.x/src/Tracy/Debugger/Debugger.php(314): Tracy\DevelopmentStrategy->renderBar() #6 [internal function]: Tracy\Debugger::shutdownHandler() #7 {main} I am using the newest PW Version and the newest Tracy Debugger Version, can anybody give me a hint what is happening here?
  10. I have a little update on this procedure: When disabling the two-factor authorization it is straight-forward and fast to add the customers instagram account into the app. First you don't have to ask the customer for the security code (on each login attempt) and second you don't need to add the clients instagram account to your facebook accounts center in the first place. When the app is working the client can feel free to re-activate the two-factor authorization.
  11. @bernhard another quick question: Is it possible to change the color (the tiny little dot) or even better, the text or background color of a type of event? Each parent page of an event has a specific category. Every category has a primary color and I want to reflect this in the event overview calendar.
  12. I just finished integrating this module on a client website (it's not live yet!) . The client has roundabout 85 groups. Each group meets on a specific date - recurring! So I added a RockCalendar field for each group and created the recurring events for each group depending on their meeting times. The group meeting times vary massively and you can think about every possible combination for example: "every second and last tuesday in every second month" and so on... This was no problem with this module! After that you can easily view and modify the events for the specific group: After creating recurring events for all of the 85 groups we now have about 5000+ event pages in the backend. This is huge! As expected from ProcessWire I did not notice any downgrades in the performance. The last thing I did - with the help of @bernhard- was to set up an "overview calendar" in the backend to get a quick look at all occurring events (for all groups): If you know how to do it this is an easy thing. You can hook into the "getEvents" method of the RockCalendar module and return custom - or modified - event data. In my case the overview calendar field is placed on the "group overview" template. This template has no direct event page children, so the overview calendar did not display anything. I used this hook to collect all event pages within the range of a month and return those events as an PageArray to the module as event data (this hook needs to be placed into the init.php!) wire()->addHookAfter('RockCalendar::getEvents', function ($event) { $pageId = $event->arguments(0); $startDate = $event->arguments(1); $endDate = $event->arguments(2); $template = wire('pages')->get($pageId)->template->name; if ($template === 'gruppe-overview') { $events = wire('pages')->find("template=event, rockcalendar_date.inRange='".$startDate." - ".$endDate."'"); $event->return = $events; } }); There you go!
  13. Thanks! You are right. After removing the HTML Entity Encoder Text Formatter form the field the decoding works.
  14. I have a trivial problem that is driving me insane. I am saving JSON Data into a field: $groupOverview->json_calendar_data = json_encode($eventsData); $groupOverview->save(); The JSON string is valid, as I have testet. In the frontend I turn this string back into an array like this: $eventsData = json_decode($groupOverview->json_calendar_data, true); bd($eventsData); The problem is: It always returns NULL. Printing out the field value as string works fine though, this is not a field selector issue.
×
×
  • Create New...