diff --git a/README.md b/README.md index 12cc09726..73f05fbfe 100644 --- a/README.md +++ b/README.md @@ -16,17 +16,17 @@ - :mag: SEO optimized - :love_letter: Write posts/pages in Markdown or [MDX](https://mdxjs.com/) - :art: Code syntax highlight - - :books: Multilang support (blog post) + - :books: Multilang support/i18n (blog post) - :iphone: Mobile Friendly (Responsive design) - :sparkles: PWA ready - :airplane: Offline support - :page_with_curl: Manifest support - [:wrench: Fully configurable (see data/siteConfig.js)](./data/siteConfig.js) - :speech_balloon: Disqus support -- :nail_care: css-in-js (with [styled-components v4](https://www.styled-components.com)) +- :nail_care: css-in-js (with [styled-components v5](https://www.styled-components.com)) - :bookmark: Groups post with tags - :bar_chart: Google Analytics support -- :bird: post preview image generation (Twitter, Facebook) +- :bird: post preview image generation (Twitter, Facebook...) - :gem: Developer tools: - eslint - prettier @@ -87,7 +87,7 @@ You can also use `gatsby-starter-morning-dew` as a [Gatsby theme](https://www.ga ], ``` 3. Add an image called `baymax.png` in `content/images/baymax.png`. -🐞This is due to a bug. +🐞This is due to a theme limitations. 😬 Don't worry, this picture will not appear on your website! Need more details? Checkout: @@ -125,7 +125,7 @@ module.exports = { authorName: 'Maxence Poutord', twitterUsername: '_maxpou', authorAvatar: 'avatar.jpeg', // file in content/images - multilangPosts: true, // enable/disable flags in post lists + defaultLang: 'en', // show flag if lang is not default. Leave empty to enable flags in post lists authorDescription: ` For the last decade, Maxence Poutord has worked with a variety of web technologies. He is currently focused on front-end development. On his day to day job, he is working as a senior front-end engineer at VSware. He is also a frequent tech speaker and a mentor. diff --git a/content/pages/how-to-install/how-to-install.md b/content/pages/how-to-install/how-to-install.md index c21050691..c71b69dcc 100644 --- a/content/pages/how-to-install/how-to-install.md +++ b/content/pages/how-to-install/how-to-install.md @@ -76,7 +76,7 @@ module.exports = { authorName: 'Maxence Poutord', twitterUsername: '_maxpou', authorAvatar: 'avatar.jpeg', // file in content/images - multilangPosts: true, // enable/disable flags in post lists + defaultLang: 'en', // show flag if lang is not default. Leave empty to enable flags in post lists authorDescription: ` For the last decade, Maxence Poutord has worked with a variety of web technologies. He is currently focused on front-end development. On his day to day job, he is working as a senior front-end engineer at VSware. He is also a frequent tech speaker and a mentor. diff --git a/content/posts/00-frontmatter-placeholder/cover.jpeg b/content/posts/00-frontmatter-placeholder/cover.jpeg new file mode 100644 index 000000000..44f52b0b1 Binary files /dev/null and b/content/posts/00-frontmatter-placeholder/cover.jpeg differ diff --git a/content/posts/00-frontmatter-placeholder/index.md b/content/posts/00-frontmatter-placeholder/index.md new file mode 100644 index 000000000..f798e5b61 --- /dev/null +++ b/content/posts/00-frontmatter-placeholder/index.md @@ -0,0 +1,20 @@ +--- +title: this post is a ghost +slug: invisible-post +date: 2020-01-01 + +# optional fields +published: false +unlisted: true +generate-card: false +language: fr +cover: ./cover.jpeg +imageShare: ./cover.jpeg +tags: ['fake'] +translations: + - link: 'https://www.maxpou.fr/about' + language: 'french' +--- + +This exists to populate GraphQL fields and avoid null errors. It should contain +all of the available frontmatter. \ No newline at end of file diff --git a/content/posts/2019-07-10-using-mdx/index-fr.mdx b/content/posts/2019-07-10-using-mdx/index-fr.mdx new file mode 100644 index 000000000..d0c763933 --- /dev/null +++ b/content/posts/2019-07-10-using-mdx/index-fr.mdx @@ -0,0 +1,52 @@ +--- +title: Utiliser MDX +slug: using-mdx-fr +date: 2019-07-10 +language: fr +unlisted: true +generate-card: false +tags: ['gatsby', 'translation'] +translations: + - link: '/using-mdx' + language: 'English' +--- + +## Salut les gens! + +Grace a à MDX, il est maintenant possible d'ajouter du JSX dans du Markdown! Juste en dessous, un example de JSX intégré dans du Markdown
+ +> MDX est un format autorisable qui vous permet d'écrire en toute transparence JSX dans vos documents Markdown. Vous pouvez importer des composants, tels que des graphiques interactifs ou des alertes, et les intégrer dans votre contenu. Cela rend l'écriture de contenu longue forme avec des composants un souffle 🚀. + + +**Example:** + +
+

Voila du JSX dans du Markdown

+ {console.log('Salut MDX')} +
+ +Code: + +```jsx +
+

Voila du JSX dans du Markdown

+ {console.log('Salut MDX')} +
+``` + + +## How-to? + +```jsx{5} +import MySuperComponent from '../path/to/MySuperComponent' + +# Du text en Markdown + + + +Un autre texte en markdown +``` + +## Read more + +👉 https://mdxjs.com \ No newline at end of file diff --git a/content/posts/2019-07-10-using-mdx/index.mdx b/content/posts/2019-07-10-using-mdx/index.mdx index dcfbd78b0..d62adb717 100644 --- a/content/posts/2019-07-10-using-mdx/index.mdx +++ b/content/posts/2019-07-10-using-mdx/index.mdx @@ -4,8 +4,10 @@ slug: using-mdx date: 2019-07-10 language: en generate-card: false -tags: - - gatsby +tags: ['gatsby', 'translation'] +translations: + - link: '/using-mdx-fr' + language: 'French' --- ## Hello, world! diff --git a/data/siteConfig.js b/data/siteConfig.js index ca87ade59..a79682dd3 100644 --- a/data/siteConfig.js +++ b/data/siteConfig.js @@ -4,7 +4,7 @@ module.exports = { authorName: 'Maxence Poutord', twitterUsername: '_maxpou', authorAvatar: 'avatar.jpeg', // file in content/images - multilangPosts: true, // enable/disable flags in post lists + defaultLang: 'en', // show flag if lang is not default. Leave empty to enable flags in post lists authorDescription: ` For the last decade, Maxence Poutord has worked with a variety of web technologies. He is currently focused on front-end development. On his day to day job, he is working as a senior front-end engineer at VSware. He is also an occasional tech speaker and a mentor. diff --git a/gatsby-node.js b/gatsby-node.js index 894a3263f..50aa89053 100644 --- a/gatsby-node.js +++ b/gatsby-node.js @@ -17,6 +17,7 @@ exports.createPages = async ({ graphql, actions, reporter }) => { { allMarkdown: allMdx( sort: { fields: [frontmatter___date], order: DESC } + filter: { frontmatter: { published: { ne: false } } } limit: 1000 ) { edges { @@ -26,6 +27,7 @@ exports.createPages = async ({ graphql, actions, reporter }) => { title slug tags + language } } } diff --git a/src/components/Article.js b/src/components/Article.js index 6c575b617..71bac6464 100644 --- a/src/components/Article.js +++ b/src/components/Article.js @@ -28,6 +28,7 @@ class Article extends React.Component { content={post.body} date={post.frontmatter.date} tags={post.frontmatter.tags} + translations={post.frontmatter.translations} /> diff --git a/src/components/Content.js b/src/components/Content.js index 30a2fefa7..c20a9f459 100644 --- a/src/components/Content.js +++ b/src/components/Content.js @@ -96,7 +96,7 @@ const ContentBody = styled.div` padding: 1; } - & .gatsby-highlight pre[class*=language-] { + & .gatsby-highlight pre[class*='language-'] { float: left; min-width: 100%; } @@ -151,11 +151,14 @@ const ContentBody = styled.div` class Content extends React.Component { render() { - const { content, date, tags } = this.props + const { content, date, tags, translations } = this.props return (
- {(tags || date) && } + {(tags || date || translations) && ( + + )} + {content} diff --git a/src/components/ContentHeader.js b/src/components/ContentHeader.js index 7e19d1b9c..2469094b2 100644 --- a/src/components/ContentHeader.js +++ b/src/components/ContentHeader.js @@ -1,6 +1,7 @@ import React, { Fragment } from 'react' import styled from 'styled-components' import TagList from './TagList' +import Translations from './Translations' import Time from './Time' import { colors } from '../tokens' import { Bull } from './Commons' @@ -13,7 +14,7 @@ const Header = styled.header` class ContentIntro extends React.Component { render() { - const { date, tags } = this.props + const { date, tags, translations } = this.props return (
@@ -24,6 +25,8 @@ class ContentIntro extends React.Component { )} + + {translations && }
) } diff --git a/src/components/PostsListItem.js b/src/components/PostsListItem.js index 15ff296aa..ea0b3a9de 100644 --- a/src/components/PostsListItem.js +++ b/src/components/PostsListItem.js @@ -53,14 +53,14 @@ const FooterLine = styled.div` const PostsListItem = props => { const { title, excerpt, slug, language, tags, timeToRead } = props - const { multilangPosts } = useSiteMetadata() + const { defaultLang } = useSiteMetadata() return (

- {multilangPosts && } + {defaultLang !== language && } {title}

diff --git a/src/components/RelatedPosts.js b/src/components/RelatedPosts.js index eac6dafe9..d1f0beca4 100644 --- a/src/components/RelatedPosts.js +++ b/src/components/RelatedPosts.js @@ -5,18 +5,18 @@ import useSiteMetadata from '../hooks/use-site-config' const RelatedPosts = props => { const { posts } = props - const { multilangPosts } = useSiteMetadata() + const { defaultLang } = useSiteMetadata() return (
    {posts.map(post => { const title = post.node.frontmatter.title const slug = post.node.frontmatter.slug - const language = post.node.frontmatter.language || 'en' + const language = post.node.frontmatter.language || defaultLang return (
  • - {multilangPosts && } + {defaultLang !== language && } {title}
  • diff --git a/src/components/SEO.js b/src/components/SEO.js index f687dfad6..54070b0ba 100644 --- a/src/components/SEO.js +++ b/src/components/SEO.js @@ -13,7 +13,9 @@ const SEO = props => { twitterUsername, } = useSiteMetadata() - const title = props.title ? `${props.title} | ${siteTitle}` : siteTitle + const title = props.title + ? `${props.title} | ${siteTitle}` + : `${siteTitle} - ${siteDescription}` const formatedSiteUrl = siteUrl.endsWith('/') ? siteUrl.substring(0, siteUrl.length - 1) : siteUrl diff --git a/src/components/Translations.js b/src/components/Translations.js new file mode 100644 index 000000000..bc2b76e1f --- /dev/null +++ b/src/components/Translations.js @@ -0,0 +1,43 @@ +import React, { Fragment } from 'react' +import styled from 'styled-components' +import { colors } from '../tokens' + +const TranslationContainer = styled.div` + border-radius: 5px; + padding: 10px; + margin-top: 10px; + background-color: ${colors.lightYellow}; + border: 1px solid ${colors.grey700}; +` + +const InfoText = styled.span` + color: ${colors.grey900}; +` + +const TranslationLink = styled.a` + color: ${colors.grey900}; + text-decoration: underline; +` + +class Translations extends React.Component { + render() { + const { translations } = this.props + + return ( + + This article also exists in: + {translations.map((translation, i) => { + return ( + + + {translation.language} + + {i < translations.length - 1 ? ', ' : ''} + + ) + })} + + ) + } +} +export default Translations diff --git a/src/hooks/use-site-config.js b/src/hooks/use-site-config.js index ed05a9e9d..2a85aca7e 100644 --- a/src/hooks/use-site-config.js +++ b/src/hooks/use-site-config.js @@ -15,7 +15,7 @@ const useSiteMetadata = () => { twitterUsername disqusShortname disqusSiteUrl - multilangPosts + defaultLang headerTitle headerLinksIcon headerLinks { diff --git a/src/pages/404.js b/src/pages/404.js index 740c8f4f6..03d992952 100644 --- a/src/pages/404.js +++ b/src/pages/404.js @@ -34,7 +34,10 @@ const NotFoundPage = props => { query { posts: allMdx( sort: { fields: [frontmatter___date], order: DESC } - filter: { fileAbsolutePath: { regex: "//content/posts//" } } + filter: { + fileAbsolutePath: { regex: "//content/posts//" } + frontmatter: { published: { ne: false }, unlisted: { ne: true } } + } limit: 5 ) { edges { diff --git a/src/templates/blog-list-template.js b/src/templates/blog-list-template.js index d32e023b8..6419327e8 100644 --- a/src/templates/blog-list-template.js +++ b/src/templates/blog-list-template.js @@ -44,7 +44,10 @@ export const pageQuery = graphql` } posts: allMdx( sort: { fields: [frontmatter___date], order: DESC } - filter: { fileAbsolutePath: { regex: "//content/posts//" } } + filter: { + fileAbsolutePath: { regex: "//content/posts//" } + frontmatter: { published: { ne: false }, unlisted: { ne: true } } + } limit: $limit skip: $skip ) { diff --git a/src/templates/blog-post.js b/src/templates/blog-post.js index 54e12c259..a0e42d450 100644 --- a/src/templates/blog-post.js +++ b/src/templates/blog-post.js @@ -64,6 +64,10 @@ export const pageQuery = graphql` imageShare { publicURL } + translations { + language + link + } } } } diff --git a/src/templates/tags.js b/src/templates/tags.js index 2bef72896..0f178303f 100644 --- a/src/templates/tags.js +++ b/src/templates/tags.js @@ -38,7 +38,13 @@ export const pageQuery = graphql` query PostsByTag($tag: String!) { posts: allMdx( sort: { fields: [frontmatter___date], order: DESC } - filter: { frontmatter: { tags: { eq: $tag } } } + filter: { + frontmatter: { + tags: { eq: $tag } + published: { ne: false } + unlisted: { ne: true } + } + } ) { edges { node { diff --git a/src/tokens/colors.js b/src/tokens/colors.js index 63b42e5b6..03035271f 100644 --- a/src/tokens/colors.js +++ b/src/tokens/colors.js @@ -13,6 +13,7 @@ const colors = { white: '#ffffff', yellow: '#ffdc4e', + lightYellow: '#f9e892', lightBlue: '#697980', }