Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Is it possible to have 2 layouts? #1494

Closed
magicly opened this issue Jul 13, 2017 · 12 comments
Closed

Is it possible to have 2 layouts? #1494

magicly opened this issue Jul 13, 2017 · 12 comments

Comments

@magicly
Copy link
Contributor

magicly commented Jul 13, 2017

hi, is it possible to have more than 1 layout? I searched issues, but can't find anything useful?

I tried #1119 method, use the code below:

 createPage({
                path: edge.node.fields.slug, // required
                component: blogPost,
                context: {
                    slug: edge.node.fields.slug,
                },
                layout: 'noFooter',
            })

but it doesn't work. Is there any examples or is it possible? thanks~

@craigmulligan
Copy link

Hey,

Atm it's currently not possible. I think @jbolda is working on it?

Two related issues: #1255 #1119

@magicly
Copy link
Contributor Author

magicly commented Jul 13, 2017

Finally I solved my problem by this code in layouts/index.jsx:

        {
          this.props.location.pathname === '/quickstart' ? '' : <Footer />
        }

@jbolda
Copy link
Contributor

jbolda commented Jul 13, 2017

Yea, currently that is the only way to do it. I just PRed my example with that. I was working on it, but had to stop for a while. Hoping someone else can pick it up.

https://github.com/gatsbyjs/gatsby/pull/1492/files

@m-allanson
Copy link
Contributor

For anyone else that ends up here - it's possible to do this by implementing the onCreatePage API in your gatsby-node.js file. See https://www.gatsbyjs.org/docs/creating-and-modifying-pages/#choosing-the-page-layout

@jrop
Copy link

jrop commented Oct 30, 2017

Again, for anybody searching here, I am using the following with success (slightly jury-rigged):

front-matter.js

// adapted from `front-matter` module
const yamlParser = require('js-yaml')

// extract /* @meta [YAML] */ comments
module.exports = function parse(string) {
	const match = /\/\*\s*@meta([\s\S]*?)\*\//.exec(string)

	if (!match) {
		return {
			attributes: {},
			body: string,
		}
	}

	const yaml = match[1].trim()
	const attributes = yamlParser.load(yaml) || {}
	const body = string.substr(match[0].length)
	return {attributes, body, frontmatter: yaml}
}

gatsby-node.js

const fm = require('./front-matter')
const fs = require(`fs-extra`)

exports.onCreatePage = async function({page}) {
	const {attributes: {layout}} = fm(await fs.readFile(page.component, 'utf8'))
	page.layout = layout || 'index'
}

With these in place, I can use frontmatter, like so:

src/pages/sample.js

/* @meta
layout: wide
*/
import React from 'react'
export default () => <div>...EXAMPLE...</div>

@gilesbutler
Copy link

gilesbutler commented Apr 7, 2018

Just came across this issue whilst searching for a way to add multiple layouts.

Not sure if Gatsby has been updated since @jrop's helpful answer. But I found https://www.gatsbyjs.org/docs/creating-and-modifying-pages/#choosing-the-page-layout.

gatsby-node.js

const path = require("path");

exports.createPages = ({ boundActionCreators, graphql }) => {
  const { createPage } = boundActionCreators;

  return graphql(`
    {
      allMarkdownRemark {
        edges {
          node {
            excerpt(pruneLength: 400)
            html
            id
            frontmatter {
              templateKey
              path
              layout
              title
            }
          }
        }
      }
    }
  `).then(result => {
    if (result.errors) {
      result.errors.forEach(e => console.error(e.toString()));
      return Promise.reject(result.errors);
    }

    return result.data.allMarkdownRemark.edges.forEach(({ node }) => {
      const pagePath = node.frontmatter.path;
      const layout = node.frontmatter.layout || "index";

      createPage({
        path: pagePath,
        layout,
        component: path.resolve(
          `src/templates/${String(node.frontmatter.templateKey)}.js`
        )
        // additional data can be passed via context
        // context: {
        // }
      });
    });
  });
};

exports.onPreBootstrap = () => {
  require("isomorphic-fetch");
};

The key lines are here...

const layout = node.frontmatter.layout || "index";

      createPage({
        path: pagePath,
        layout,

It assumes your main layout file is index.jsx

src/pages/sample.md

---
templateKey: 'sample-page'
path: /sample
layout: NEW_LAYOUT_FILE_NAME
title: Sample
---

Then just add NEW_LAYOUT_FILE_NAME.jsx to your layout folder, restart the server and you should be good to go.


Update 11/04/2018
This breaks the build when deploying to Netlify due to #1846

Update 11/04/2018
Turns out this does actually work! The build was breaking due to another issue 🙄

@PolGuixe
Copy link
Contributor

PolGuixe commented Jun 4, 2018

@gilesbutler

Can you add

---
templateKey: 'sample-page'
path: /sample
layout: NEW_LAYOUT_FILE_NAME
title: Sample
---

to a JS file? isn't this for MarkDown?

@gilesbutler
Copy link

Good spot @PolGuixe 👍

I've updated my example src/pages/sample.js should have been src/pages/sample.md

@PolGuixe
Copy link
Contributor

PolGuixe commented Jun 5, 2018

@gilesbutler How would you use it in .js files?

@gilesbutler
Copy link

You can't as far as I know. It was a typo and was supposed to be for MarkDown.

@sabbakeynejad
Copy link

sabbakeynejad commented Sep 18, 2018

If you just need to make small changes, I just use conditional rendering.

{post.frontmatter.tag == 'blog' && <p className="project-cat"> — {post.frontmatter.date}</p> }

@exocode
Copy link

exocode commented May 23, 2020

For anyone else that ends up here - it's possible to do this by implementing the onCreatePage API in your gatsby-node.js file. See https://www.gatsbyjs.org/docs/creating-and-modifying-pages/#choosing-the-page-layout

I cannot anything find at this link which corresponds with "Choosing ghe page layout". Did Gatsby changed the content? is there a "2020" approach or plugin?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

9 participants