Jump to content

Relaunch: barmbek-nord.info (community portal for a district of Hamburg, germany)


Stefanowitsch
 Share

Recommended Posts

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:

 


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.

image.thumb.png.ac5a9039f761661c3b5d9c26ba3d084c.png

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:

image.thumb.jpeg.11cbd201a491fe03dbcc38e42846257d.jpeg

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

image.thumb.jpeg.44eaa37d00a48198d6f7514d68b29458.jpegA 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 Pageimage.thumb.png.b8b36676d6b2845a3b0314b74e1881eb.png

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:

image.png.d120df401bbfcaa6d1df434f1830d69f.png

 

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:

image.png.2695eb0afa04977bdb7d32d397bcca69.png

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”:

image.png.cf25da5da80e9c1fa4b530c9106b5377.png

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:

image.thumb.png.96cbf6b203dbfafde8c77f1d9ee5e647.png

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:

 

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/

image.jpeg

  • Like 1
  • Thanks 4
Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...