Skip to main content
Ctrl+K
⚠️ You are viewing the 2022 version of Plone Training. View the latest version. ⚠️

Plone Training 2022

Trainings

  • Mastering Plone 6 Development
    • About Mastering Plone
    • Watch the Training Video
    • Introduction
    • The Case Study
    • What is Plone?
    • Set up Plone
    • Set up Plone for the Training
    • The Features of Plone
    • What's New in Plone?
    • Configuring and Customizing Plone "Through The Web"
    • Customizing Volto Components
    • Semantic UI
    • Theming in Volto
    • Extending Plone
    • Extending Plone With Add-on Packages
    • Write Your Own Python Add-On to Customize Plone
    • Dexterity I: Content types
    • Dexterity II: Talks
    • Dexterity: Reference
    • Volto App Development
    • Volto View Component: A Default View for a "Talk"
    • Behaviors
    • Creating a dynamic frontpage with Volto blocks
    • Programming Plone
    • IDEs and Editors
    • Turning Talks into Events
    • Vocabularies, Registry-Settings and Control Panels
    • Custom Search
    • Upgrade-steps
    • Testing in Plone
    • Using Third-Party Behaviors
    • Dexterity Types III: Sponsors
    • The Sponsors Component
    • Using Volto add-ons
    • Extending Volto With Custom Add-on Package
    • Extending Volto With a FAQ Block Type
    • Workflow, Roles and Permissions
    • Relations
    • Reusable Features packaged in add-ons
    • Complex Behaviors
    • REST API Endpoints
    • Volto Actions and Component State
    • Permissions
    • Releasing Your Code
    • Using plone.restapi without Volto
    • Using the code for the training
    • Trainer: Preparation
  • Mastering Plone 5 Development
    • About Mastering Plone
    • Introduction
    • What is Plone?
    • Installation & Setup
    • Installing Plone for the Training
    • What Vagrant is and does
    • The Case Study
    • The Features of Plone
    • The Anatomy of Plone
    • What's New in Plone 5, 5.1 and Plone 5.2
    • Configuring and Customizing Plone "Through The Web"
    • Theming
    • Extending Plone
    • Extend Plone With Add-On Packages
    • Dexterity I: "Through The Web"
    • Buildout I
    • Write Your Own Add-Ons to Customize Plone
    • Return to Dexterity: Moving contenttypes into Code
    • Views I
    • Page Templates
    • Customizing Existing Templates
    • Views II: A Default View for "Talk"
    • Views III: A Talk List
    • Testing in Plone
    • Behaviors
    • Writing Viewlets
    • Programming Plone
    • IDEs and Editors
    • Dexterity Types II: Growing Up
    • Custom Search
    • Turning Talks into Events
    • User Generated Content
    • Resources
    • Using Third-Party Behaviors
    • Dexterity Types III: Python
    • Dexterity: Reference
    • Relations
    • Manage Settings with Registry, Control Panels and Vocabularies
    • Creating a Dynamic Front Page
    • Creating Reusable Packages
    • More Complex Behaviors
    • A Viewlet for the Votable Behavior
    • Making Our Package Reusable
    • Using starzel.votable_behavior in ploneconf.site
    • Releasing Your Code
    • Buildout II: Getting Ready for Deployment
    • Plone REST API
    • The Future of Plone
    • Optional
    • Using the code for the training
  • React
    • Introduction
    • Watch the Training Video
    • Bootstrapping A React Project
    • Create React Component
    • Styling Your Component
    • Convert To A Reusable Component
    • Use Snapshot Testing
    • How To Use State In Your Component
    • Use Event Handlers
    • Use Callbacks To Delete An Item
    • Use Forms To Add An Item
    • Use Initial Form Data To Edit An Item
    • Use Redux To Store Data
    • Write Tests For Your Reducers
    • Use Actions To Manipulate The Store
    • Using External Data
    • useEffect Hook
    • Using Different Routes
    • Using Links To Navigate
    • Navigate Using Redirects
  • Volto
    • Introduction
    • Code Walkthrough
    • Bootstrapping a Volto project
    • Styling
    • Static Resources
    • Override Components
    • Internationalization
    • Override Views
    • Custom Views
    • Custom Widget
    • Rich Text Editor Settings
    • Actions & Reducers
  • Volto Hands-On
    • Introduction
    • Quick Start
    • Project requirements
    • Theming
    • Header
    • Breadcrumbs
    • Footer
    • Edit config and site cleanup
    • Brief introduction to Volto blocks
    • Blocks - Highlight Block
    • Configurable Downloadlink Block
    • Events listing template
    • Sprint content type
  • Volto Add-ons Development
    • Introduction
    • Volto add-ons development
    • Basic working block
    • Improve the block view
    • Block editing with a form
    • Customizable columns
    • Make the block extensible
    • Add-ons - advanced topics
    • Plone integration with Volto blocks
    • About
    • Developer integration with text editors
    • Really short primer on Javascript enhancements
  • Effective Volto
    • About Effective Volto
    • Getting Started
      • Bootstrapping a full Plone 6 project
      • Bootstrapping an Add-on
      • Developer roadmap
    • Architecture
      • Volto Client - Server duality
      • Razzle
      • Webpack
      • Babel
      • Webpack loaders
      • Bootstrap Volto
      • Inside Volto
      • Volto Blocks
      • Configuration Registry
      • Redux
      • CORS
      • Multilingual
    • Backend
      • Plone REST API endpoints
      • Writing an endpoint
      • Writing a serializer or a deserializer
      • Writing a content expansion endpoint
      • Writing a block transform
      • Block field contribute to searchableText
      • Link integrity for blocks
      • Writing Express middleware
    • Add-ons
      • What is a Volto add-on
      • Bootstrap an add-on
      • How does a Volto add-on works?
      • Configure a released Volto Add-on in your project
      • Configure an unreleased add-on from an existing repository
      • Volto views
      • Create a block using BlockDataForm
      • Blocks Layout
      • Block Extensions
      • Block Styling
      • Add-on dependencies
      • Add-on and project configuration pipeline
      • Create a theme add-on
      • Extending Semantic UI
      • Create a custom Listing block variation
      • Integrate with Volto’s asyncConnect for SSR
      • Add-on Internationalization
      • Extend Webpack setup from an add-on with razzle.extend.js
    • Testing
      • Acceptance testing
      • Jest
      • Unit testing
      • Storybook
      • Testing add-ons
    • Deployment
      • Seamless mode
      • Simple deployment
      • Docker
      • release-it
    • Development tools
      • How to setup your development environment using environment variables
      • Environment variables
      • Icons
      • Husky and lint-staged
      • Shortcuts
      • Internationalization
      • Lazyloading components, injectLazyLibs for libraries
      • critical.css
      • Bundle analyzing
      • Component Registry
      • Linters
      • Debugging with Volto
      • VSCode extensions/helpers
      • vim and neovim integration
  • Testing Plone
    • Summary
    • Intro to tests
    • Some theory
    • How to test a Plone add-on
    • Testing setup
    • Unit tests
    • Testing a Dexterity content type
    • Testing a view
    • Acceptance testing
    • Robot tests
    • Continuous Integration
  • Plone 6 Classic UI Theming
    • Preparation for the theming training
    • TTW Customizations
    • Create a theme based on Barceloneta
    • Create a Theme from scratch
    • Create a theme based on Diazo
  • Plone 5 Theming
    • Basic TTW Customizations
    • TTW Theming I: Introduction
    • TTW Theming II: Custom Barceloneta Theme
    • TTW Theming III: Make It Reproducible
    • Theme Package I: Preparations
    • Theme Package II: Diazo Theme
    • Theme Package III: Customizations
    • Theme Package IV: Templates
    • Theme Package V: Initial Content
    • Theme Package VI: TinyMCE Templates
    • Theme Package VII: Resource Registries
    • Advanced Diazo
    • Jbot
    • Creating Custom Components
  • JavaScript For Plone Developers (up to Plone 5)
    • Setup
    • JavaScript Development Process
    • RequireJS And JavaScript Modules
    • Mockup
    • Writing Documentation For Mockup
    • Through-The-Web Development
    • Exercises
      • Exercise 1: Include a JavaScript resource TTW
      • Exercise 2: Include JavaScript In Browser View
      • Exercise 3: Gallery Integration With Theme
      • Exercise 4: Gallery integration as resources
      • Exercise 5: Simple Pattern
      • Exercise 6: Using A Pattern In A Z3C Form Widget
      • Exercise 7: Pattern Wrapping A 3rd Party Library
      • Exercise 8: Customizing Pattern
      • Exercise 9: Overriding a pattern TTW
      • Exercise 10: NG2 APP Component Rendered In A Browser View
      • Exercise 11: NG2 APP Component In a A bundle
      • Exercise 12: NG2 APP In Logged In Bundle
      • Exercise 13: Pattern with React
    • Scratchpad
  • Plone Deployment
    • Introduction
    • Training setup
    • Introduction to Plone stack
    • Plone Docker Images
    • Create a Project
    • Editing your project
    • Server Setup
    • Deploy
  • Automating Plone Deployment
    • Introduction
    • Intro To Plone Stack
    • Intro To Ansible
    • The Plone Playbook
    • Basic Use Of The Playbook
    • In Operation
    • Customized Use
    • Maintenance Strategies
    • Plone Deployments With Amazon OpsWorks
      • Introduction
      • Deployment Terminology
      • Creating Your First Stack
      • Deploying Changes
      • Maintenance
      • What Doesn't It Do
    • Introduction
    • Deployment Terminology
    • Creating Your First Stack
    • Deploying Changes
    • Maintenance
    • What Doesn't It Do
    • Let's Encrypt Certificates and certbot
  • Plone Deployments With Amazon OpsWorks
    • Introduction
    • Deployment Terminology
    • Creating Your First Stack
    • Deploying Changes
    • Maintenance
    • What Doesn't It Do
  • Deploying and Operating Plone on WSGI
    • Setup a box for the training
    • PEP 3333
    • Deploying Plone with WSGI using zc.buildout, plone.recipe.zope2instance and Waitress
    • Differences to the ZServer setup
    • Understanding the contents of wsgi.ini
    • What's left in zope.conf?
    • WSGI options
    • Bjoern
    • Gunicorn
    • uWSGI
    • Debugging Plone on WSGI
    • Useful Add-ons and Utilities
    • Can I talk to the supervisor?
    • Buildout for the training
  • "Through-The-Web" Plone Customization
    • Customizing logo and CSS of default theme
    • Configuring and Customizing Plone
    • Introduction to Diazo Theming
    • Creating a custom theme based on Barceloneta
    • Dexterity
    • Mosaic
    • Rapido
    • Workflow
  • Integrate Plone with Solr
    • Setup
    • Solr GUI And Query Syntax
    • First Steps
    • How Does collective.solr Work
    • Solr Buildout Configuration
    • More Features
    • Solr Testing
    • Production Setup
    • Alternative Indexing/Search Solutions
  • Plone Workflow
    • Introduction To Workflows
    • Basic Roles and Permissions
    • Local Roles
    • Dynamic Roles
    • Placeful Workflow
    • Multi-chain Workflows
    • Workflow Variables
    • Using GenericSetup to Manage Plone Workflows
  • Migration best practices
    • Migrating Plone
    • In-place migrations
    • Migrating with collective.exportimport
    • Migrate to Volto
    • Migrating from third party systems to Plone
  • Migrating Content with Transmogrifier
    • Export Current Site Content
    • Transmogrifier Basics
    • Before Running the Import
    • Writing the Import Pipeline
    • Writing Custom Blueprints
    • Running the Import
    • Advanced Pipeline Tips
    • Advanced Blueprint Tips
    • Users & Groups Migration
  • GatsbyJS
    • Summary
    • What Is GatsbyJS
    • How it works
    • Installing The Development Environment
    • Pages
    • Data
    • Source plugins
    • Transformer plugins
    • Dynamic pages
    • Building Source Plugins
    • Fetching Data Using Plone REST.API
    • Search Traversal Method Of Retrieving Data
    • gatsby-source-plone
    • gatsby-starter-plone
    • Copying The Plone Site
    • RichText Component
    • Navigation
  • Angular SDK for Plone
    • Summary
    • What Is Angular
    • What Is The Plone Angular SDK
    • Installing The Development Environment
    • Using And Customizing The Angular Plone Components
    • Integrating A Theme
    • Override A default Plone Component Template
    • Creating A Custom View For The Talk Content Type
    • Displaying News On The Home Page
    • Login
    • Adding Quick Links In the Footer
    • Deployment
    • Managing The Plone Configuration From The Angular Project
    • Advanced
  • Build your own webframework from scratch
    • About this course
    • The Web and Python
    • Hello WSGI
    • Middlewares
    • Routing
    • From Raw WSGI to a framework
    • Exploiting Python's data model
    • Metaclasses
    • Functional Python
    • Summary

Appendices

  • Glossary
  • Contributing to Plone Training
    • Building and Checking the Quality of Documentation
    • General Guide to Writing Documentation
    • Authors Guide
  • Teaching
    • 1. Training theory: education, how people learn and process information
    • 2. Before the training: Create material, invite trainees, preparation
    • 3. During training day(s): what to expect, do's and don'ts
    • 4. After the training: Aftercare, keep in touch, learn, improve
  • Repository
  • Suggest edit
  • Open issue
  • .md

Header

Contents

  • Header styling
  • Logo
  • Header component
  • Component shadowing
  • Page content

Header#

Header styling#

We will start introducing the basic styling for the header. We use the theme/extras/custom.overrides to apply general styling to our site theme.

Note

Use this rule of thumb when building Volto themes: use the default Semantic overrides system when the override is site-wide and applies to Semantic components. When using your own components and specific theme styling, use instead custom.overrides. Applying styling later using this method is much faster than doing it in the Semantic default components. Dont feel confused by the fact, that the header still does look a bit "weird" in comparison to the plone.org one

This :

.ui.basic.segment.header-wrapper {
  background: #007eb6;
  color: @white;
  padding: 0 0 1em 0;
  .top-header {
    background-color: #1f1238;
    width: 100%;
    margin-bottom: 1em;
    .ui.container {
      display: flex;
      justify-content: flex-end;
      text-transform: uppercase;
      font-weight: bold;
      font-size: 11px;
      a {
        color: @white;
        margin-right: 10px;
      }
    }
  }
  .nav-wrapper {
    display: flex;
    align-items: baseline;
    text-transform: uppercase;

    .ui.secondary.pointing.menu .item,
    .ui.pointing.dropdown {
      color: @white;
      border: none;
      padding: 0.5em 0.8em;
      border-radius: 5px;
      margin-right: 5px;
      font-size: 14px;
      &:first-child {
        display: none;
      }

      &.active,
      &:hover {
        background-color: #1a0b31;
      }
    }

    .ui.button.search {
      background: transparent;
      padding: 0.5em 0.8em;
      border-radius: 5px;
      color: @white;
      font-weight: normal;
      text-transform: uppercase;

      &:hover {
        background-color: #1a0b31;
      }
      .icon {
        margin-bottom: -2px;
      }
    }
  }
}

Then we adjust the margin for the content area:

.ui.basic.segment.content-area {
  padding-top: 0;
  margin-top: 0;
}

Logo#

We use component shadowing to customize (and override) Volto original components. Get the Plone logo (Logo.svg) from the training-resources you downloaded from the google drive.

Note

Every time you add a file to the customizations folder or to the theme folder, you must restart Volto for changes to take effect. From that point on, the hot reloading should kick in and reload the page automatically.

Header component#

We will customize the existing Volto header, since the one we want does not differ much from the original. We will do so by copying the original Volto Header component from the omelette folder omelette/src/components/theme/Header/Header.jsx folder into src/customizations/components/theme/Header/Header.jsx.

Note

If you have not worked with React that much so far you will notice that the Navigation component in Volto is not a javascipt function. This is because in React components can also be created from a js class. Actually this was the preffered way to create components in earlier versions of React. Volto is currently undergoing the progress to switch to function components where possible. But as Volto has already a rather extensive codebase this is still an ongoing process.

We have to make some more changes to that component, such as removing the search widget and the Anontools component, adding the upper Header section and many more amendmends.

This will be the outcome:

import { Container, Segment, Dropdown } from 'semantic-ui-react';
import {
  Anontools,
  Logo,
  Navigation,
  Icon,
  UniversalLink,
} from '@plone/volto/components';
import zoomSVG from '@plone/volto/icons/zoom.svg';
...

render() {
    return (
     <Segment basic className="header-wrapper" role="banner">
        <div className="top-header">
          <Container>
            <UniversalLink href="https://2022.ploneconf.org">
              Conference
            </UniversalLink>
            <UniversalLink href="https://docs.plone.org">
              Documentation
            </UniversalLink>
            <UniversalLink href="https://training.plone.org">
              Training
            </UniversalLink>
            <UniversalLink href="https://community.plone.org">
              Forum
            </UniversalLink>
            <UniversalLink href="https://discord.com/invite/zFY3EBbjaj">
              Chat
            </UniversalLink>
          </Container>
        </div>
        <Container>
          <div className="header">
            <div className="logo">
              <Logo />
            </div>
            <div className="nav-wrapper">
              <Navigation pathname={this.props.pathname} />
              <Dropdown text="More" pointing>
                <Dropdown.Menu>
                  <Dropdown.Item>
                    <UniversalLink href="/about-plone">
                      About Plone
                    </UniversalLink>
                  </Dropdown.Item>
                  <Dropdown.Item>
                    <UniversalLink href="/conferences">
                      Conferences
                    </UniversalLink>
                  </Dropdown.Item>
                  <Dropdown.Item>
                    <UniversalLink href="/donate">Donate</UniversalLink>
                  </Dropdown.Item>
                  <Dropdown.Item>
                    <UniversalLink href="/download">Download</UniversalLink>
                  </Dropdown.Item>
                  <Dropdown.Item>
                    <UniversalLink href="/features">Features</UniversalLink>
                  </Dropdown.Item>
                  <Dropdown.Item>
                    <UniversalLink href="/events">Events</UniversalLink>
                  </Dropdown.Item>
                  <Dropdown.Item>
                    <UniversalLink href="/news">News</UniversalLink>
                  </Dropdown.Item>
                  <Dropdown.Item>
                    <UniversalLink href="/providers">Providers</UniversalLink>
                  </Dropdown.Item>
                  <Dropdown.Item>
                    <UniversalLink href="/related">
                      Related websites
                    </UniversalLink>
                  </Dropdown.Item>
                  <Dropdown.Item>
                    <UniversalLink href="/security">Security</UniversalLink>
                  </Dropdown.Item>
                  <Dropdown.Item>
                    <UniversalLink href="/support">Support</UniversalLink>
                  </Dropdown.Item>
                  <Dropdown.Item>
                    <UniversalLink href="/newsroom">Newsroom</UniversalLink>
                  </Dropdown.Item>
                  <Dropdown.Item>
                    <UniversalLink href="/products">Products</UniversalLink>
                  </Dropdown.Item>
                </Dropdown.Menu>
              </Dropdown>
              <div className="tools-search-wrapper">
                <div className="tools-search">
                  <UniversalLink href="/search" className="ui button search">
                    <Icon name={zoomSVG} size="18px" color="white" />
                    Search
                  </UniversalLink>
                </div>
                {!this.props.token && (
                  <div className="tools">
                    <Anontools />
                  </div>
                )}
              </div>
            </div>
          </div>
        </Container>
      </Segment>
    );
  }

Component shadowing#

We use a technique called component shadowing to override an existing Volto component with our local custom version, without having to modify Volto's source code at all. You have to place the replacing component in the same original folder path inside the src/customizations folder. Take the src directory in Volto as the root when recreating the path in /customizations.

Note

Component shadowing is very much like the good old Plone technique called "JBOT" ("just a bunch of templates"), but you can customize virtually any module in Volto, including actions and reducers, not only components.

Page content#

To have the header look as much as the plone.org page as possible you now can create the pages "get started", "community" and plone foundation to be featured in the navigation.

previous

Theming

next

Breadcrumbs

Contents
  • Header styling
  • Logo
  • Header component
  • Component shadowing
  • Page content

By Plone Community

© Copyright The text and illustrations in this website are licensed by the Plone Foundation under a Creative Commons Attribution 4.0 International license.