Programming Notes
Think it, Code it, Run it    moschini.cloud  

Layout del sito
Data pubblicazione: 02 settembre 2022

Lavoriamo sul layout

In questo articolo vedremo come rendere il nostro blog un po' più accattivante, lavorando sul layout.

Andremo ad aggiungere header, footer, navigation bar e, in generale, vedremo come creare componenti riutilizzabili.

In particolare, definiremo:

  • un componente che implementa l' Header, all'interno del quale andremo a posizionare l'intestazione del sito e, subito sotto, la navigation bar per spostarci tra le pagine;
  • un altro componente per il Footer, in cui andremo a mettere, ad esempio, le informazioni di contatto;
  • infine, un componente, Layout, che incapsula i due componenti Header e Footer, in modo da utilizzare solo quest'ultimo nelle pagine del blog.

Prerequisiti

Occorre installare alcun plugin che ci faciliteranno lo sviluppo del sito per gli aspetti che riguardano gli stylesheets e l'utilizzo di particolari font.

Iniziamo con l'installazione del plugin gatsby-plugin-sass con il comando:

    npm install sass gatsby-plugin-sass

Quindi, modifichiamo il file gatsby-config.js ed aggiungiamo la voce `gatsby-plugin-sass` all'interno della sezione plugins.

Tramite questa aggiunta, possiamo scrivere i nostri stylesheets dentro un file con estensione .scss e importarlo come un qualsiasi componente.

Installiamo anche il plugin gatsby-plugin-google-fonts con il comando:

    npm install gatsby-plugin-google-fonts

per utilizzare i Google Fonts: per il nostro blog, utilizzeremo il font Roboto, per cui andremo a specificare nel file gatsby-config.js (sezione plugin) queste impostazioni:

    {
      resolve: `gatsby-plugin-google-fonts`,
      options: {
        fonts: [
                  `roboto`
               ],
        display: 'swap'
      }
    },

Componente Header

Per struttura il codice sorgente in modo ordinato, creiamo una directory che conterrà i componenti. Dentro la directory src creiamo la directory components e, all'interno, creiamo i file:

  • header.js: conterrà il codice per definire il componente Header;
  • header.module.scss: è il foglio di stile con gli stylesheets utilizzati da header.js:
Blog
Nota

Come regola generale, ogni componente sarà composto da due file:

  • un file con estensione .js conterrà la definizione del componente;

  • un file con estensione .scss oppure .css conterrà la definizione degli stylesheets utilizzati dal componente.


All'interno del file header.js inseriamo questo codice:

import * as React from "react"
import { Link } from "gatsby"
import { graphql } from "gatsby"
import { useStaticQuery } from 'gatsby'
import * as styles from "./header.module.scss"

export default function Header() {

    const data = useStaticQuery(headerQuery)
    const { title, description, author } = data.site.siteMetadata

    return (
        <>
            <header className={styles.header}>
                <Link className={styles.linkHome} to="/">
                    <p className={styles.title}>{title} - {author}</p>
                    <p className={styles.description}>{description}</p>
                </Link>

                <div className={styles.menu}>
                    <ul className={styles.navigation}>
                        <li><Link to="/" activeClassName={styles.navigationActive} className={styles.navigation}>Home</Link></li>
                        <li><Link to="/about/" activeClassName={styles.navigationActive} className={styles.navigation}>About</Link></li>
                    </ul>
                </div>
            </header>
        </>
    )
}

const headerQuery = graphql`
    query headerQuery {
        site {
            siteMetadata {
            title
            description
            author
            }
        }
    }
`

Nel file header.module.scss inseriamo questo codice:

.header {
  background-color: #0d4faa;
  font-family: Roboto;
  padding-top: 10px;
  padding-bottom: 10px;
  padding-left: 20px;
  padding-right: 20px;
}

.linkHome {
    color: #d9e9f1;
    text-decoration: none;
}

.title {
  font-family: Roboto;
  font-size: 24pt;
  font-weight: bold;
  margin: 0px;
}

.description {
  font-family: Roboto;
  font-size: 16pt;
  margin: 0px;
}

.menu {
  font-family: Roboto;
  color: #ffffff;
  background-color: #444444;
  margin-top: 10px;
}

ul.navigation {
  list-style-type: none;
  margin-left: 0px;
  margin-right: 0px;
  overflow: hidden;
  background-color: #358b5c;
  margin-block-start: 0px;
  margin-block-end: 0px;
  padding-inline-start: 0px;
}

ul.navigation > li {
  display: block;
  float: left;
}

.navigation {
  text-decoration: none;
  color: white;
}

ul.navigation > li a {
  display: block;
  color: white;
  text-align: center;
  text-decoration: none;
  padding: 14px 16px;
  font-size: 22px;
}

ul.navigation > li a:hover {
  background-color: rgb(145, 218, 131);
}

.navigationActive {
  background-color: rgb(112, 172, 104);
}

Componente Footer

Analogamente a quanto fatto per il componente Header, nella directory components creiamo i file:

  • footer.js: conterrà il codice per definire il componente Footer;
  • footer.module.scss: è il foglio di stile con gli stylesheets utilizzati da footer.js:
Blog

All'interno del file footer.js inseriamo questo codice:

import * as React from "react"
import { graphql } from "gatsby"
import { useStaticQuery } from 'gatsby'
import * as styles from "./footer.module.scss"

export default function Footer() {

  const data = useStaticQuery(footerQuery)
  const { title, author } = data.site.siteMetadata

  return (
    <footer className={styles.footer}>
      <div>
        <h1>
          <div className={styles.text}>
            2022 - {author} - {title}
          </div>
          <div className={styles.text}>
            <a href="mailto:info@moschini.cloud">
              info@moschini.cloud
            </a>
          </div>
        </h1>
      </div>
    </footer>
  )
}

const footerQuery = graphql`
    query footerQuery {
      site {
        siteMetadata {
          title
          author
        }
      }
    }
  `

Nel file footer.module.scss inseriamo questo codice:

.footer {
  background-color: #b1c7e6;
  margin-top: 30px;
  font-family: Roboto;
  padding-top: 10px;
  padding-bottom: 10px;
  padding-left: 20px;
  padding-right: 20px;
  position: relative;
  bottom: 0;
}

.text {
  color: rgb(7, 93, 133);
  text-decoration: none;
  font-family: Roboto;
  font-size: 14pt;
  font-weight: normal;
  text-align: center;
}

Componente Layout

Infine, per il componente Layout, nella directory components creiamo i file:

  • layout.js: conterrà il codice per definire il componente Layout;
  • layout.module.scss: è il foglio di stile con gli stylesheets utilizzati da layout.js:
Blog

il cui contenuto è:

layout.js:

import * as React from "react"
import PropTypes from "prop-types"
import Header from "./header"
import Footer from "./footer"
import * as styles from "./layout.module.scss"

const Layout = ({ children }) => {
  return (
    <>
      <Header>
      </Header>

      <div className={styles.maincontent}>
        <main>
          {children}
        </main>
      </div>

      <Footer>
      </Footer>
    </>
  )
}

Layout.propTypes = {
  children: PropTypes.node.isRequired
}

export default Layout

layout.module.scss:

* {
  box-sizing: border-box;
}

.maincontent {
  margin-top: 0px;
  margin-bottom: 0px;
  margin-left: 150px;
  margin-right: 150px;
  font-family: Roboto;
}

Utilizzo del componente Layout

A questo punto, abbiamo il necessario per standardizzare il layout di tutte le pagine del blog. Cominciamo dalla home page, ovvero dal file index.js, il cui codice lo andremo a sostituire con questo:

import React from "react"
import { graphql } from "gatsby"
import { Link } from 'gatsby'
import Layout from "../components/layout"

export default function Home({ data }) {
  const { title, description, author } = data.site.siteMetadata

  return (
    <div>
      <Layout>
        <h1>{title}</h1>
        <p>{description}</p>
        <p>{author}</p>
        <Link to="about">About</Link>
      </Layout>
    </div>
  )
}

export const pageQuery = graphql`
  query MetadataQuery {
    site {
      siteMetadata {
        title
        description
        author
      }
    }
  }
`

Le differenze rispetto alla versione precedente riguardano:

  • l'importazione del componente Layout
  • il suo utilizzo tramite i tag <Layout> ... </Layout>: ciò che abbiamo messo tra il tag di apertura e quello di chiusura è il contenuto della pagina, quindi qualsiasi ulteriore aggiunta di codice deve essere fatta all'interno della sezione <Layout> ... </Layout>. In questo modo, se tutte le pagine del sito utilizzeranno il componente Layout, avremo una completa uniformità dell'interfaccia visuale.

In modo analogo, il codice della pagina di About (file: about.js) lo modificheremo come segue:

import * as React from "react"
import { StaticImage } from "gatsby-plugin-image"
import Layout from "../components/layout"

const About = () => (
    <div>
        <Layout>
            <h1>Mi chiamo Fabio Moschini e sono un programmatore.</h1>
            <p>Puoi inviarmi una email a questo indirizzo:
                <a href="mailto:info@moschini.cloud">
                    info@moschini.cloud
                </a>
            </p>

            <StaticImage
                layout="fullWidth"
                alt="notebook"
                src="../images/notebook.jpg"
            />
        </Layout>
    </div>
)

export default About

Anche in questo caso, tutto il contenuto della pagina è racchiuso tra i tag <Layout> ... </Layout>.

Il risultato finale è:

Blog
Blog