Security News
Fluent Assertions Faces Backlash After Abandoning Open Source Licensing
Fluent Assertions is facing backlash after dropping the Apache license for a commercial model, leaving users blindsided and questioning contributor rights.
gatsby-plugin-templated-files
Advanced tools
Gatsby plugin that converts a folder of files of any type into Gatsby pages via template components.
Allows directories of files to be turned into pages in GatsbyJS (v2) via a React template component. Effectively works like gatsby-plugin-page-creator
but for files of any type.
The primary use for this will be to crawl a directory of Markdown files and turn them into pages matching that folder heirarchy but without adding boilerplate page-creation code in gatsby-node.js
file and without needing any gatsby-source-filesystem
configuration.
You do still need the gatsby-transformer-remark
plugin to parse your files into Markdown. The example below shows a template using these two plugins together.
npm install gatsby-plugin-templated-files
Add the following to your gatsby-config.js
file (note you can include multiple instances of the plugin to create separate sets of autopages):
// gatsby-config.js
module.exports = {
plugins: {
{
resolve: "gatsby-plugin-templated-files",
options: {
path: "mypages",
template: "Page.jsx",
},
},
{
resolve: "gatsby-plugin-templated-files",
options: {
// Crawl the ./blog/ directory.
path: "blog",
// Template file (absolute, or relative to src/templates)
template: `${__dirname}/src/othertemplates/Blog.jsx`,
// Set a format for the URL (defaults to "/:slug")
url: "/blog/:slug",
// Files to include (defaults to .md and *.markdown only).
include: [
"**/*.txt",
"**/*.md",
"**/*.html",
]
// Files to ignore.
ignore: [
"**/LICENSE.txt",
"**/LICENSE.md",
],
// Files to use as directory indexes (defaults to index.* and README.*)
indexes: [
"**/README.md",
"**/sitepage.html",
"**/index.*",
]
},
},
{
resolve: "gatsby-plugin-templated-files",
options: {
path: "./pastas",
template: "Pasta.jsx",
},
},
"gatsby-plugin-remark"
}
}
options.path
(required)String path to directory of files to create corresponding pages for, e.g. src/blog/
gatsby-config.js
is!)options.template
(required)String path to the *.js
or *.jsx
template file the pages should use, e.g. Blog.jsx
src/templates
directorysrc/templates
, e.g. MyTemplate.jsx
${__dirname}/src/other/MyOtherTemplate.js
options.url
(optional)Set the output URL format for pages. Defaults to /:slug
/:slug/
/blog/:slug
:slug
is the only available variable — open an issue if you need moreoptions.include
(optional)Array of file globs to include when crawling your options.path
dir. If specified will replace the default list:
**/*.md
**/*.markdown
options.ignore
(optional)Array of file globs to ignore when crawling. If specified will add to the default list (dotfiles and npm files):
**/.*
**/yarn.lock
**/package.json
**/package-lock.json
**/node_modules
options.indexes
Array of file globs to use as index files, e.g. if listing.md
is an index then a/b/c/listing.md
will have the a/b/c
slug (with no listing
). Defaults to:
**/index.*
**/README.*
To output your Markdown as HTML (via React) you'll need to create a template file. These files are just normal GatsbyJS page components which have two requirements:
default export
a React componentquery
// src/templates/Pasta.jsx
import React from "react";
import { graphql } from "gatsby";
// Component.
export default function Pasta({ data }) {
const file = data.templated;
const markdown = file.childMarkdownRemark;
return (
<article>
<h1>{markdown.frontmatter.title || file.name}</h1>
<div dangerouslySetInnerHTML={{ __html: markdown.html }} />
</article>
);
}
// Query.
export const query = graphql`
query($id: String!) {
templated(id: { eq: $id }) {
absolutePath # '/usr/var/www/pastas/Ribbon Pasta/Tagliatelli.md'
relativePath # 'Ribbon Pasta/Tagliatelli.md'
name # 'Tagliatelli'
dirs # ['Ribbon Pasta']
childMarkdownRemark {
html # '...parsed Markdown content of Tagliatelli.md...'
frontmatter {
title # '...title parsed from frontmatter of Tagliatelli.md...'
}
}
}
}
`;
This GraphQL query retrieves a single Templated
file node. All fields in the node (like name
, extension
, size
, dir
, depth
) can be used for filtering and sorting, except for content
which is lazy-loaded.
query($id: String!) {
templated(id: { eq: $id }) {
id # 'b82587df-f952-5201-85c5-bcb9df3a17ca'
absolutePath # '/usr/var/www/pastas/Ribbon Pasta/Tagliatelli.md'
relativePath # 'Ribbon Pasta/Tagliatelli.md'
rootPath # 'pastas/Ribbon Pasta/Tagliatelli.md'
templatePath # '/usr/var/www/src/templates/Pasta.jsx'
index # false (would be true for e.g. index.md)
base # 'Tagliatelli.md'
name # 'Tagliatelli'
extension # 'md'
dir # 'Ribbon Pasta'
dirs # ['Ribbon Pasta']
slug # 'ribbon-pasta/tagliatelli'
slugs # ['ribbon-pasta', 'tagliatelli']
depth # 2
url # '/ribbon-pasta/tagliatelli'
size # 1048576
prettySize # '1 MB'
modifiedTime # 'Mon Oct 22 2018 01:01:33 GMT'
accessedTime # 'Mon Oct 22 2018 01:01:33 GMT'
changedTime # 'Mon Oct 22 2018 01:01:33 GMT'
birthtime # 'Mon Oct 22 2018 01:01:33 GMT'
content # '...entire raw contents of Tagliatelli.md...'
internal {
type # 'Templated'
mediaType # 'text/markdown'
contentDigest # '2b365824e5c9240509bc33ec15b05070'
}
}
}
If you're using gatsby-transformer-remark
it's recommended to query the Templated
file node first, then add in the child MarkdownRemark
node using childMarkdownRemark
:
query($path: String!) {
templated(rootPath: { eq: $path }) {
absolutePath # '/usr/var/www/pastas/Ribbon Pasta/Tagliatelli.md'
rootPath # 'pastas/Ribbon Pasta/Tagliatelli.md'
name # 'Tagliatelli'
dirs # ['Ribbon Pasta']
childMarkdownRemark {
html # '...parsed Markdown content of Tagliatelli.md...'
frontmatter {
title # '...title parsed from frontmatter of Tagliatelli.md...'
}
}
}
}
Query for a list of files with an allTemplated
query. Results can again be filtered and sorted using any of the Templated
node's fields.
{
allTemplated(filter: { name: { eq: "abc" } }, sort: { fields: [rootPath], order: DESC }) {
edges {
node {
base # 'Tagliatelli.md'
extension # 'md'
dir # 'Ribbon Pasta'
modifiedTime # 'Mon Oct 22 2018 01:01:33 GMT'
}
}
}
}
Query heirarchically nested children of the matched file with the following query. You can use this to output your entire tree of files (up to a required depth) e.g. to build navigation menus or sidebars. You could make this neater with a fragment but we've made it explicit for the example.
Heirarchy in this plugin constructs based on the final page URL (i.e. based on your options.url
setting). So pages at /a/x
and /a/y
become children of the page at /a
).
If you're receiving an error that childrenTemplated
does not exist, use childTemplated
instead. Gatsby creates these automatically based on whether any Templated
nodes in your project have multiple children. This is annoying but there's no easy workaround.
{
allTemplated(filter: { depth: { eq: 0 } }) {
edges {
node {
depth # 0
name # ''
dirs # []
relativePath # 'index.md'
childMarkdownRemark {
frontmatter {
title # 'Pasta Database'
}
}
childrenTemplated {
depth # 1
name # 'Ribbon Pasta'
dirs # []
relativePath # 'Ribbon Pasta/index.md'
childMarkdownRemark {
frontmatter {
title # 'Ribbon Pasta'
}
}
childrenTemplated {
depth # 2
name # 'Tagliatelli'
dirs # ['Ribbon Pasta']
relativePath # 'Ribbon Pasta/Tagliatelli.md'
childMarkdownRemark {
frontmatter {
title # 'Tagliatelli'
}
}
}
}
}
}
}
}
Useful PRs are welcomed! Code must pass ESLint (with Prettier via eslint-prettier, Jest unit tests, and Cypress end-to-end tests. Run this locally with yarn test
and wait for it to be confirmed by TravisCI.
All commits on the master branch are deployed automatically using semantic-release which bumps version numbers automatically based on commit messages, so Commits must follow Conventional Commits. This is enforced by a Husky precommit hook.
FAQs
Gatsby plugin that converts a folder of files of any type into Gatsby pages via template components.
The npm package gatsby-plugin-templated-files receives a total of 8 weekly downloads. As such, gatsby-plugin-templated-files popularity was classified as not popular.
We found that gatsby-plugin-templated-files demonstrated a not healthy version release cadence and project activity because the last version was released a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Security News
Fluent Assertions is facing backlash after dropping the Apache license for a commercial model, leaving users blindsided and questioning contributor rights.
Research
Security News
Socket researchers uncover the risks of a malicious Python package targeting Discord developers.
Security News
The UK is proposing a bold ban on ransomware payments by public entities to disrupt cybercrime, protect critical services, and lead global cybersecurity efforts.