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 daheader.js
:
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 dafooter.js
:
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 dalayout.js
:
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 è: