├── gatsby-browser.js ├── .prettierrc ├── src ├── images │ └── gatsby-icon.png ├── pages │ ├── blog │ │ ├── use-reasonml │ │ │ └── index.md │ │ ├── index.js │ │ └── how-types-improve-javascript │ │ │ └── index.md │ ├── index.js │ └── 404.js ├── components │ └── layout.js └── templates │ └── blog-post.js ├── static └── images │ └── iwilsonq.jpg ├── .graphql_ppx_cache ├── graphql_schema.json.hash └── graphql_schema.json.marshaled ├── .gitignore ├── gatsby-ssr.js ├── re ├── Utils.re ├── types │ ├── Gatsby.bs.js │ └── Gatsby.re ├── Utils.bs.js ├── Blog.re ├── Bio.re ├── Post.re ├── Blog.bs.js ├── Header.re ├── Index.re ├── Index.bs.js ├── Bio.bs.js ├── Post.bs.js └── Header.bs.js ├── bsconfig.json ├── gatsby-config.js ├── LICENSE ├── .merlin ├── package.json ├── .eslintrc.js ├── gatsby-node.js └── README.md /gatsby-browser.js: -------------------------------------------------------------------------------- 1 | import 'normalize-css' 2 | -------------------------------------------------------------------------------- /.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "semi": false, 3 | "singleQuote": true, 4 | "trailingComma": "es5" 5 | } 6 | -------------------------------------------------------------------------------- /src/images/gatsby-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iwilsonq/gatsby-starter-reasonml/HEAD/src/images/gatsby-icon.png -------------------------------------------------------------------------------- /static/images/iwilsonq.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iwilsonq/gatsby-starter-reasonml/HEAD/static/images/iwilsonq.jpg -------------------------------------------------------------------------------- /.graphql_ppx_cache/graphql_schema.json.hash: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iwilsonq/gatsby-starter-reasonml/HEAD/.graphql_ppx_cache/graphql_schema.json.hash -------------------------------------------------------------------------------- /.graphql_ppx_cache/graphql_schema.json.marshaled: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iwilsonq/gatsby-starter-reasonml/HEAD/.graphql_ppx_cache/graphql_schema.json.marshaled -------------------------------------------------------------------------------- /src/pages/blog/use-reasonml/index.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Use ReasonML 3 | date: 2018-10-27T22:40:32.169Z 4 | path: use-reasonml 5 | --- 6 | 7 | It's a pretty neat language. -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Project dependencies 2 | .cache 3 | node_modules 4 | yarn-error.log 5 | 6 | # Build directory 7 | /public 8 | .DS_Store 9 | 10 | # BuckleScript 11 | /lib 12 | -------------------------------------------------------------------------------- /gatsby-ssr.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Implement Gatsby's SSR (Server Side Rendering) APIs in this file. 3 | * 4 | * See: https://www.gatsbyjs.org/docs/ssr-apis/ 5 | */ 6 | 7 | // You can delete this file if you're not using it 8 | -------------------------------------------------------------------------------- /re/Utils.re: -------------------------------------------------------------------------------- 1 | // str = "2018-10-27T22:40:32.169Z" 2 | // result = "Sunday, February 17, 2019" 3 | 4 | let formatDate = (isoDateString: string) => { 5 | DateFns.internal_format(Js.Date.fromString(isoDateString), "dddd, MMMM D, YYYY"); 6 | }; -------------------------------------------------------------------------------- /src/pages/index.js: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | 3 | import Layout from '../components/layout' 4 | import Index from '../../re/Index.bs' 5 | 6 | const IndexPage = () => ( 7 | 8 | 9 | 10 | ) 11 | 12 | export default IndexPage 13 | -------------------------------------------------------------------------------- /re/types/Gatsby.bs.js: -------------------------------------------------------------------------------- 1 | // Generated by BUCKLESCRIPT VERSION 5.0.2, PLEASE EDIT WITH CARE 2 | 'use strict'; 3 | 4 | 5 | var Link = /* module */[]; 6 | 7 | var StaticQuery = /* module */[]; 8 | 9 | exports.Link = Link; 10 | exports.StaticQuery = StaticQuery; 11 | /* No side effect */ 12 | -------------------------------------------------------------------------------- /src/pages/404.js: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import Layout from '../components/layout' 3 | 4 | const NotFoundPage = () => ( 5 | 6 |

NOT FOUND

7 |

You just hit a route that doesn't exist... the sadness.

8 |
9 | ) 10 | 11 | export default NotFoundPage 12 | -------------------------------------------------------------------------------- /re/Utils.bs.js: -------------------------------------------------------------------------------- 1 | // Generated by BUCKLESCRIPT VERSION 5.0.2, PLEASE EDIT WITH CARE 2 | 'use strict'; 3 | 4 | var Format = require("date-fns/format"); 5 | 6 | function formatDate(isoDateString) { 7 | return Format(new Date(isoDateString), "dddd, MMMM D, YYYY"); 8 | } 9 | 10 | exports.formatDate = formatDate; 11 | /* date-fns/format Not a pure module */ 12 | -------------------------------------------------------------------------------- /bsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "react-template", 3 | "reason": { 4 | "react-jsx": 3 5 | }, 6 | "sources": { 7 | "dir": "re", 8 | "subdirs": true 9 | }, 10 | "package-specs": [{ 11 | "module": "commonjs", 12 | "in-source": true 13 | }], 14 | "suffix": ".bs.js", 15 | "namespace": true, 16 | "bs-dependencies": [ 17 | "reason-react", 18 | "bs-css", 19 | "bs-date-fns" 20 | ], 21 | "ppx-flags": [ 22 | "graphql_ppx/ppx" 23 | ], 24 | "refmt": 3 25 | } -------------------------------------------------------------------------------- /re/types/Gatsby.re: -------------------------------------------------------------------------------- 1 | module Link = { 2 | [@bs.module "gatsby"] [@react.component] 3 | external make: 4 | (~_to: string, ~className: string, ~children: React.element) => 5 | React.element = 6 | "Link"; 7 | }; 8 | 9 | /* WIP: StaticQuery. Try to use from the top level page components in pure JS. Its easier for now */ 10 | module StaticQuery = { 11 | [@bs.module "gatsby"] [@react.component] 12 | external make: (~query: string, ~children: React.element) => React.element = 13 | "StaticQuery"; 14 | }; -------------------------------------------------------------------------------- /re/Blog.re: -------------------------------------------------------------------------------- 1 | let str = React.string; 2 | 3 | type post = { 4 | . 5 | "id": string, 6 | "excerpt": string, 7 | "frontmatter": { 8 | . 9 | title: string, 10 | date: string, 11 | }, 12 | }; 13 | 14 | [@react.component] 15 | let make = (~posts) => { 16 | let renderPosts = 17 | posts 18 | |> Array.map(post => 19 | 25 | ) 26 | |> React.array; 27 |

{"Blog" |> str}

renderPosts
; 28 | }; 29 | 30 | let default = make; -------------------------------------------------------------------------------- /gatsby-config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | siteMetadata: { 3 | title: 'Gatsby ReasonML Starter', 4 | author: 'Ian Wilson', 5 | }, 6 | plugins: [ 7 | 'gatsby-plugin-react-helmet', 8 | { 9 | resolve: `gatsby-plugin-manifest`, 10 | options: { 11 | name: 'gatsby-starter-reasonml', 12 | short_name: 'starter-reasonml', 13 | start_url: '/', 14 | background_color: '#663399', 15 | theme_color: '#663399', 16 | display: 'minimal-ui', 17 | icon: 'src/images/gatsby-icon.png', // This path is relative to the root of the site. 18 | }, 19 | }, 20 | { 21 | resolve: `gatsby-source-filesystem`, 22 | options: { 23 | name: `pages`, 24 | path: `${__dirname}/src/pages`, 25 | }, 26 | }, 27 | 'gatsby-transformer-remark', 28 | 'gatsby-plugin-offline', 29 | ], 30 | } 31 | -------------------------------------------------------------------------------- /re/Bio.re: -------------------------------------------------------------------------------- 1 | let str = React.string; 2 | module Styles = { 3 | open Css; 4 | 5 | let wrapper = style([display(`flex), marginBottom(px(16))]); 6 | let img = 7 | style([ 8 | width(px(64)), 9 | height(px(64)), 10 | borderRadius(px(32)), 11 | marginRight(px(12)), 12 | ]); 13 | 14 | let bioText = style([display(`flex), alignItems(`center)]); 15 | }; 16 | 17 | [@react.component] 18 | let make = () => { 19 |
20 | Ian Wilson 21 |

22 | {"Written by Ian Wilson who lives and works in Cupertino building useful things." 23 | |> str} 24 | 25 | {"You should follow him on Twitter" |> str} 26 | 27 |

28 |
; 29 | }; 30 | 31 | let default = make; -------------------------------------------------------------------------------- /re/Post.re: -------------------------------------------------------------------------------- 1 | let str = React.string; 2 | 3 | module Styles = { 4 | open Css; 5 | let article = style([marginBottom(px(32))]); 6 | let link = 7 | style([ 8 | textDecoration(`none), 9 | hover([textDecoration(`underline), textDecorationColor(red)]), 10 | ]); 11 | let h2 = style([color(red)]); 12 | let p = style([color(black)]); 13 | let date = style([color(darkgray)]); 14 | }; 15 | 16 | [@react.component] 17 | let make = (~post) => { 18 |
19 | 21 |

{post##frontmatter##title |> str}

22 |
23 |

{post##excerpt}

24 | 25 | {post##frontmatter##date |> Utils.formatDate |> str} 26 | 27 |
; 28 | }; -------------------------------------------------------------------------------- /re/Blog.bs.js: -------------------------------------------------------------------------------- 1 | // Generated by BUCKLESCRIPT VERSION 5.0.2, PLEASE EDIT WITH CARE 2 | 'use strict'; 3 | 4 | var $$Array = require("bs-platform/lib/js/array.js"); 5 | var React = require("react"); 6 | var Post$ReactTemplate = require("./Post.bs.js"); 7 | 8 | function str(prim) { 9 | return prim; 10 | } 11 | 12 | function Blog(Props) { 13 | var posts = Props.posts; 14 | var renderPosts = $$Array.map((function (post) { 15 | return React.createElement(Post$ReactTemplate.make, { 16 | post: post, 17 | key: post.id 18 | }); 19 | }), posts); 20 | return React.createElement("div", undefined, React.createElement("h1", undefined, "Blog"), renderPosts); 21 | } 22 | 23 | var make = Blog; 24 | 25 | var $$default = Blog; 26 | 27 | exports.str = str; 28 | exports.make = make; 29 | exports.$$default = $$default; 30 | exports.default = $$default; 31 | exports.__esModule = true; 32 | /* react Not a pure module */ 33 | -------------------------------------------------------------------------------- /src/pages/blog/index.js: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import { StaticQuery, graphql } from 'gatsby' 3 | 4 | import Layout from '../../components/layout' 5 | import Blog from '../../../re/Blog.bs' 6 | 7 | const BlogPage = () => ( 8 | 9 | { 29 | const posts = data.allMarkdownRemark.edges.map(edge => edge.node) 30 | return 31 | }} 32 | /> 33 | 34 | ) 35 | 36 | export default BlogPage 37 | -------------------------------------------------------------------------------- /re/Header.re: -------------------------------------------------------------------------------- 1 | module Styles = { 2 | open Css; 3 | let header = 4 | style([backgroundColor(hex("db4d3f")), marginBottom(px(16))]); 5 | let content = 6 | style([ 7 | display(`flex), 8 | alignItems(`center), 9 | justifyContent(`spaceBetween), 10 | margin2(~v=px(0), ~h=`auto), 11 | maxWidth(px(1000)), 12 | padding2(~v=px(16), ~h=px(24)), 13 | ]); 14 | let h1 = style([margin(px(0))]); 15 | let link = style([color(white), textDecoration(none)]); 16 | let nav = style([]); 17 | }; 18 | 19 | [@react.component] 20 | let make = (~siteTitle) => { 21 |
22 |
23 |

24 | 25 | {siteTitle |> ReasonReact.string} 26 | 27 |

28 | 33 |
34 |
; 35 | }; 36 | 37 | let default = make; -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2015 gatsbyjs 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | 23 | -------------------------------------------------------------------------------- /re/Index.re: -------------------------------------------------------------------------------- 1 | let str = React.string; 2 | 3 | /* For a page of static text like this one, it would be easier to just use plain React 4 | components since we don't get to take advantage of Reason's type system */ 5 | [@react.component] 6 | let make = () => { 7 |
8 |

{"Gatsby" ++ {js| ❤ |js} ++ "ReasonML" |> str}

9 |

10 | {"Use this starter to create static sites with Gatsby using ReasonML components." 11 | |> str} 12 |

13 |

{"Features" |> str}

14 | 28 |

{"Reference" |> str}

29 | 38 |
; 39 | }; 40 | 41 | let default = make; -------------------------------------------------------------------------------- /src/pages/blog/how-types-improve-javascript/index.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: How a Type System Improves your JavaScript Code 3 | date: 2018-10-27T22:40:32.169Z 4 | path: how-types-improve-javascript 5 | --- 6 | 7 | Vanilla JavaScript is untyped by nature, some will call it “smart” because it is able to figure out what is a number or a string. 8 | 9 | This makes it easier to run JavaScript code, it simply needs to be executed in a browser or Node.js runtime. However, its vulnerable to numerous runtime errors that can spoil your user experience. 10 | 11 | If you’ve ever experienced the following, you would benefit from adopting a type system. 12 | 13 | - After fetching a list of data you may find that a certain field doesn’t exist on one of the records, causing the app to crash unless explicitly handled. 14 | - An instance of a class you imported doesn’t have a method you’re trying to invoke. 15 | - Your IDE doesn’t know what methods and properties are available, so it cannot easily assist you with autocomplete. 16 | - Difficulty reasoning about code, type systems at a glance make it easier to refactor 17 | 18 | ## Flow, TypeScript, or ReasonML 19 | 20 | If you have an existing codebase that you wish to make bulletproof, with respect to type errors, you could try adopting Flow or TypeScript. They have a fairly similar syntax. 21 | -------------------------------------------------------------------------------- /.merlin: -------------------------------------------------------------------------------- 1 | ####{BSB GENERATED: NO EDIT 2 | B lib/bs 3 | FLG -open ReactTemplate 4 | FLG -ppx /Users/ianwilson/reason-workspace/gatsby-starter-reasonml/node_modules/graphql_ppx/ppx 5 | FLG -ppx '/Users/ianwilson/reason-workspace/gatsby-starter-reasonml/node_modules/bs-platform/lib/reactjs_jsx_ppx_2.exe' 6 | FLG -ppx /Users/ianwilson/reason-workspace/gatsby-starter-reasonml/node_modules/bs-platform/lib/bsppx.exe 7 | S /Users/ianwilson/reason-workspace/gatsby-starter-reasonml/node_modules/bs-platform/lib/ocaml 8 | B /Users/ianwilson/reason-workspace/gatsby-starter-reasonml/node_modules/bs-platform/lib/ocaml 9 | FLG -nostdlib -color always 10 | FLG -w -30-40+6+7+27+32..39+44+45+101 11 | S /Users/ianwilson/reason-workspace/gatsby-starter-reasonml/node_modules/reason-react/lib/ocaml 12 | B /Users/ianwilson/reason-workspace/gatsby-starter-reasonml/node_modules/reason-react/lib/ocaml 13 | S /Users/ianwilson/reason-workspace/gatsby-starter-reasonml/node_modules/bs-css/lib/ocaml 14 | B /Users/ianwilson/reason-workspace/gatsby-starter-reasonml/node_modules/bs-css/lib/ocaml 15 | S /Users/ianwilson/reason-workspace/gatsby-starter-reasonml/node_modules/bs-date-fns/lib/ocaml 16 | B /Users/ianwilson/reason-workspace/gatsby-starter-reasonml/node_modules/bs-date-fns/lib/ocaml 17 | S re 18 | B lib/bs/re 19 | S re/types 20 | B lib/bs/re/types 21 | ####BSB GENERATED: NO EDIT} 22 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "gatsby-starter-reasonml", 3 | "description": "Gatsby starter to create static sites using type-safe ReasonML.", 4 | "version": "2.0.0", 5 | "author": "Ian Wilson ", 6 | "dependencies": { 7 | "bs-css": "^11.0.0", 8 | "bs-date-fns": "^0.1.6", 9 | "bs-platform": "^5.2.1", 10 | "core-js": "^3.4.7", 11 | "gatsby": "^2.18.6", 12 | "gatsby-plugin-manifest": "^2.2.31", 13 | "gatsby-plugin-offline": "^3.0.26", 14 | "gatsby-plugin-react-helmet": "^3.1.16", 15 | "gatsby-source-filesystem": "^2.1.40", 16 | "gatsby-transformer-remark": "^2.6.39", 17 | "normalize-css": "^2.3.1", 18 | "react": "^16.12.0", 19 | "react-dom": "^16.12.0", 20 | "react-helmet": "^5.2.1", 21 | "reason-react": "^0.7.0" 22 | }, 23 | "keywords": [ 24 | "gatsby" 25 | ], 26 | "license": "MIT", 27 | "scripts": { 28 | "postinstall": "bsb -make-world", 29 | "build": "gatsby build", 30 | "dev:bsb": "bsb -make-world -w", 31 | "dev:gatsby": "gatsby develop", 32 | "clean": "bsb -clean-world", 33 | "format": "prettier --write '**/*.js'", 34 | "test": "echo \"Error: no test specified\" && exit 1" 35 | }, 36 | "devDependencies": { 37 | "graphql_ppx": "^0.2.8", 38 | "prettier": "^1.19.1" 39 | }, 40 | "repository": { 41 | "type": "git", 42 | "url": "https://github.com/iwilsonq/gatsby-starter-reasonml" 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /src/components/layout.js: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import PropTypes from 'prop-types' 3 | import Helmet from 'react-helmet' 4 | import { StaticQuery, graphql } from 'gatsby' 5 | 6 | import Header from '../../re/Header.bs' 7 | 8 | const Layout = ({ children }) => ( 9 | ( 20 | <> 21 | 31 | 32 | 33 |
34 |
43 | {children} 44 |
45 | 46 | )} 47 | /> 48 | ) 49 | 50 | Layout.propTypes = { 51 | children: PropTypes.node.isRequired, 52 | } 53 | 54 | export default Layout 55 | -------------------------------------------------------------------------------- /re/Index.bs.js: -------------------------------------------------------------------------------- 1 | // Generated by BUCKLESCRIPT VERSION 5.0.2, PLEASE EDIT WITH CARE 2 | 'use strict'; 3 | 4 | var React = require("react"); 5 | 6 | function str(prim) { 7 | return prim; 8 | } 9 | 10 | function Index(Props) { 11 | return React.createElement("div", undefined, React.createElement("h1", undefined, "Gatsby" + (" ❤ " + "ReasonML")), React.createElement("p", undefined, "Use this starter to create static sites with Gatsby using ReasonML components."), React.createElement("h2", undefined, "Features"), React.createElement("ul", undefined, React.createElement("li", undefined, React.createElement("a", { 12 | href: "https://github.com/reasonml/reason-react" 13 | }, "reason-react"), " for type-safe React components in ReasonML"), React.createElement("li", undefined, React.createElement("a", { 14 | href: "https://github.com/SentiaAnalytics/bs-css" 15 | }, "bs-css"), " for css-in-reason styling")), React.createElement("h2", undefined, "Reference"), React.createElement("ul", undefined, React.createElement("li", undefined, "see re/Header.re for example component implementation"), React.createElement("li", undefined, "see re/types/Gatsby.re for example BuckleScript bindings to Gatsby module"))); 16 | } 17 | 18 | var make = Index; 19 | 20 | var $$default = Index; 21 | 22 | exports.str = str; 23 | exports.make = make; 24 | exports.$$default = $$default; 25 | exports.default = $$default; 26 | exports.__esModule = true; 27 | /* react Not a pure module */ 28 | -------------------------------------------------------------------------------- /.eslintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | extends: ['standard'], 3 | plugins: ['standard', 'react'], 4 | rules: { 5 | 'no-var': 'error', // optional, recommended when using es6+ 6 | 'no-unused-vars': 1, // recommended 7 | 'arrow-spacing': ['error', { 'before': true, 'after': true }], // recommended 8 | 'indent': ['error', 2], 9 | 'comma-dangle': ['error', { 10 | 'objects': 'only-multiline', 11 | 'arrays': 'only-multiline', 12 | 'imports': 'never', 13 | 'exports': 'never', 14 | 'functions': 'never' 15 | }], 16 | "strict": ["never"], 17 | 18 | // options to emulate prettier setup 19 | 'semi': ['error', 'never'], 20 | 'max-len': ['error', { 'code': 80 }], 21 | 'template-curly-spacing': ['error', 'always'], 22 | 'arrow-parens': ['error', 'as-needed'], 23 | 24 | // standard.js 25 | 'space-before-function-paren': ['error', { 26 | 'named': 'always', 27 | 'anonymous': 'always', 28 | 'asyncArrow': 'always' 29 | }], 30 | 31 | // standard plugin - options 32 | 'standard/object-curly-even-spacing': ['error', 'either'], 33 | 'standard/array-bracket-even-spacing': ['error', 'either'], 34 | 'standard/computed-property-even-spacing': ['error', 'even'], 35 | 'standard/no-callback-literal': ['error', ['cb', 'callback']], 36 | 37 | // react plugin - options 38 | 'react/jsx-uses-react': 'error', 39 | 'react/jsx-uses-vars': 'error' 40 | }, 41 | parser: 'babel-eslint', 42 | parserOptions: { 43 | 'ecmaVersion': 8, // optional, recommended 6+ 44 | } 45 | } -------------------------------------------------------------------------------- /src/templates/blog-post.js: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import Helmet from 'react-helmet' 3 | import { Link, graphql } from 'gatsby' 4 | 5 | import Bio from '../../re/Bio.bs' 6 | import Layout from '../components/layout' 7 | 8 | class BlogPostTemplate extends React.Component { 9 | render() { 10 | const post = this.props.data.markdownRemark 11 | const siteTitle = this.props.data.site.siteMetadata.title 12 | const siteDescription = post.excerpt 13 | 14 | return ( 15 | 16 | 21 |

{post.frontmatter.title}

22 |

27 | {post.frontmatter.date} 28 |

29 |
30 |
31 | 32 | 33 | ) 34 | } 35 | } 36 | 37 | export default BlogPostTemplate 38 | 39 | export const pageQuery = graphql` 40 | query BlogPostBySlug($slug: String) { 41 | site { 42 | siteMetadata { 43 | title 44 | author 45 | } 46 | } 47 | markdownRemark(fields: { slug: { eq: $slug } }) { 48 | id 49 | excerpt 50 | html 51 | frontmatter { 52 | title 53 | date(formatString: "MMMM DD, YYYY") 54 | path 55 | } 56 | } 57 | } 58 | ` 59 | -------------------------------------------------------------------------------- /gatsby-node.js: -------------------------------------------------------------------------------- 1 | const path = require('path') 2 | const { createFilePath } = require('gatsby-source-filesystem') 3 | exports.createPages = ({ graphql, actions }) => { 4 | const { createPage } = actions 5 | 6 | return new Promise((resolve, reject) => { 7 | const blogPost = path.resolve('./src/templates/blog-post.js') 8 | resolve( 9 | graphql( 10 | ` 11 | { 12 | allMarkdownRemark { 13 | edges { 14 | node { 15 | fields { 16 | slug 17 | } 18 | frontmatter { 19 | title 20 | } 21 | } 22 | } 23 | } 24 | } 25 | ` 26 | ).then(result => { 27 | if (result.errors) { 28 | reject(result.errors) 29 | } 30 | 31 | // Create blog posts pages. 32 | const posts = result.data.allMarkdownRemark.edges 33 | 34 | posts.forEach(post => { 35 | createPage({ 36 | path: post.node.fields.slug, 37 | component: blogPost, 38 | context: { 39 | slug: post.node.fields.slug, 40 | }, 41 | }) 42 | }) 43 | }) 44 | ) 45 | }) 46 | } 47 | 48 | exports.onCreateNode = ({ node, actions, getNode }) => { 49 | const { createNodeField } = actions 50 | 51 | if (node.internal.type === `MarkdownRemark`) { 52 | const value = createFilePath({ node, getNode }) 53 | createNodeField({ 54 | name: `slug`, 55 | node, 56 | value, 57 | }) 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /re/Bio.bs.js: -------------------------------------------------------------------------------- 1 | // Generated by BUCKLESCRIPT VERSION 5.0.2, PLEASE EDIT WITH CARE 2 | 'use strict'; 3 | 4 | var Css = require("bs-css/src/Css.js"); 5 | var React = require("react"); 6 | 7 | function str(prim) { 8 | return prim; 9 | } 10 | 11 | var wrapper = Css.style(/* :: */[ 12 | Css.display(/* flex */-1010954439), 13 | /* :: */[ 14 | Css.marginBottom(Css.px(16)), 15 | /* [] */0 16 | ] 17 | ]); 18 | 19 | var img = Css.style(/* :: */[ 20 | Css.width(Css.px(64)), 21 | /* :: */[ 22 | Css.height(Css.px(64)), 23 | /* :: */[ 24 | Css.borderRadius(Css.px(32)), 25 | /* :: */[ 26 | Css.marginRight(Css.px(12)), 27 | /* [] */0 28 | ] 29 | ] 30 | ] 31 | ]); 32 | 33 | var bioText = Css.style(/* :: */[ 34 | Css.display(/* flex */-1010954439), 35 | /* :: */[ 36 | Css.alignItems(/* center */98248149), 37 | /* [] */0 38 | ] 39 | ]); 40 | 41 | var Styles = /* module */[ 42 | /* wrapper */wrapper, 43 | /* img */img, 44 | /* bioText */bioText 45 | ]; 46 | 47 | function Bio(Props) { 48 | return React.createElement("div", { 49 | className: wrapper 50 | }, React.createElement("img", { 51 | className: img, 52 | alt: "Ian Wilson", 53 | src: "/images/iwilsonq.jpg" 54 | }), React.createElement("p", { 55 | className: bioText 56 | }, "Written by Ian Wilson who lives and works in Cupertino building useful things.", React.createElement("a", { 57 | href: "https://twitter.com/iwilsonq" 58 | }, "You should follow him on Twitter"))); 59 | } 60 | 61 | var make = Bio; 62 | 63 | var $$default = Bio; 64 | 65 | exports.str = str; 66 | exports.Styles = Styles; 67 | exports.make = make; 68 | exports.$$default = $$default; 69 | exports.default = $$default; 70 | exports.__esModule = true; 71 | /* wrapper Not a pure module */ 72 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 |

2 | 3 | Gatsby 4 | 5 |

6 |

7 | Gatsby ReasonML Starter 8 |

9 | 10 | This starter for Gatsby is inspired by the default starter blog. Except this one supports ReasonML with its strongly typed, functional goodness. 11 | 12 | ## 🚀 Quick start 13 | 14 | 1. **Install the Gatsby CLI.** 15 | 16 | The Gatsby CLI helps you create new sites using Gatsby starters (like this one!) 17 | 18 | ```sh 19 | # install the Gatsby CLI globally 20 | npm install -g gatsby-cli 21 | ``` 22 | 23 | 2. **Create a Gatsby site.** 24 | 25 | Use the Gatsby CLI to create a new site, specifying the default starter.◊ 26 | 27 | ```sh 28 | # create a new Gatsby site using the ReasonML starter 29 | gatsby new my-super-neat-reasonml-site https://github.com/iwilsonq/gatsby-starter-reasonml 30 | ``` 31 | 32 | 3. **Start developing.** 33 | 34 | Navigate into your new site’s directory and start it up. 35 | 36 | ```sh 37 | cd my-super-neat-reasonml-site/ 38 | npm run dev:bsb 39 | npm run dev:gatsby 40 | ``` 41 | 42 | 4. **Open the source code and start editing!** 43 | 44 | Your site is now running at `http://localhost:8000`! 45 | 46 | \_Note: You'll also see a second link: `http://localhost:8000/___graphql`. This is a tool you can use to experiment with querying your data. Learn more about using this tool in the [Gatsby tutorial](https://www.gatsbyjs.org/tutorial/part-five/#introducing-graphiql).\_ 47 | 48 | Open the the `my-super-neat-reasonml-site` directory (or whatever sensible name you gave it) in your code editor of choice and edit `src/pages/index.js`. Save your changes and the browser will update in real time! 49 | 50 | ## 🧐 What's inside? 51 | 52 | - Gatsby v2 53 | - BuckleScript platform v4 54 | - [bs-css](https://github.com/SentiaAnalytics/bs-css) (based on [emotion](https://emotion.sh)) 55 | - [bs-date-fns](https://github.com/SllyQ/bs-date-fns) 56 | -------------------------------------------------------------------------------- /re/Post.bs.js: -------------------------------------------------------------------------------- 1 | // Generated by BUCKLESCRIPT VERSION 5.0.2, PLEASE EDIT WITH CARE 2 | 'use strict'; 3 | 4 | var Css = require("bs-css/src/Css.js"); 5 | var React = require("react"); 6 | var Gatsby = require("gatsby"); 7 | var Utils$ReactTemplate = require("./Utils.bs.js"); 8 | 9 | function str(prim) { 10 | return prim; 11 | } 12 | 13 | var article = Css.style(/* :: */[ 14 | Css.marginBottom(Css.px(32)), 15 | /* [] */0 16 | ]); 17 | 18 | var link = Css.style(/* :: */[ 19 | Css.textDecoration(/* none */-922086728), 20 | /* :: */[ 21 | Css.hover(/* :: */[ 22 | Css.textDecoration(/* underline */131142924), 23 | /* :: */[ 24 | Css.textDecorationColor(Css.red), 25 | /* [] */0 26 | ] 27 | ]), 28 | /* [] */0 29 | ] 30 | ]); 31 | 32 | var h2 = Css.style(/* :: */[ 33 | Css.color(Css.red), 34 | /* [] */0 35 | ]); 36 | 37 | var p = Css.style(/* :: */[ 38 | Css.color(Css.black), 39 | /* [] */0 40 | ]); 41 | 42 | var date = Css.style(/* :: */[ 43 | Css.color(Css.darkgray), 44 | /* [] */0 45 | ]); 46 | 47 | var Styles = /* module */[ 48 | /* article */article, 49 | /* link */link, 50 | /* h2 */h2, 51 | /* p */p, 52 | /* date */date 53 | ]; 54 | 55 | function Post(Props) { 56 | var post = Props.post; 57 | return React.createElement("article", { 58 | className: article 59 | }, React.createElement(Gatsby.Link, { 60 | to: "/blog/" + post.frontmatter.path, 61 | className: link, 62 | children: React.createElement("h2", { 63 | className: h2 64 | }, post.frontmatter.title) 65 | }), React.createElement("p", { 66 | className: p 67 | }, post.excerpt), React.createElement("small", { 68 | className: date 69 | }, Utils$ReactTemplate.formatDate(post.frontmatter.date))); 70 | } 71 | 72 | var make = Post; 73 | 74 | exports.str = str; 75 | exports.Styles = Styles; 76 | exports.make = make; 77 | /* article Not a pure module */ 78 | -------------------------------------------------------------------------------- /re/Header.bs.js: -------------------------------------------------------------------------------- 1 | // Generated by BUCKLESCRIPT VERSION 5.0.2, PLEASE EDIT WITH CARE 2 | 'use strict'; 3 | 4 | var Css = require("bs-css/src/Css.js"); 5 | var React = require("react"); 6 | var Gatsby = require("gatsby"); 7 | 8 | var header = Css.style(/* :: */[ 9 | Css.backgroundColor(Css.hex("db4d3f")), 10 | /* :: */[ 11 | Css.marginBottom(Css.px(16)), 12 | /* [] */0 13 | ] 14 | ]); 15 | 16 | var content = Css.style(/* :: */[ 17 | Css.display(/* flex */-1010954439), 18 | /* :: */[ 19 | Css.alignItems(/* center */98248149), 20 | /* :: */[ 21 | Css.justifyContent(/* spaceBetween */516682146), 22 | /* :: */[ 23 | Css.margin2(Css.px(0), /* auto */-1065951377), 24 | /* :: */[ 25 | Css.maxWidth(Css.px(1000)), 26 | /* :: */[ 27 | Css.padding2(Css.px(16), Css.px(24)), 28 | /* [] */0 29 | ] 30 | ] 31 | ] 32 | ] 33 | ] 34 | ]); 35 | 36 | var h1 = Css.style(/* :: */[ 37 | Css.margin(Css.px(0)), 38 | /* [] */0 39 | ]); 40 | 41 | var link = Css.style(/* :: */[ 42 | Css.color(Css.white), 43 | /* :: */[ 44 | Css.textDecoration(Css.none), 45 | /* [] */0 46 | ] 47 | ]); 48 | 49 | var nav = Css.style(/* [] */0); 50 | 51 | var Styles = /* module */[ 52 | /* header */header, 53 | /* content */content, 54 | /* h1 */h1, 55 | /* link */link, 56 | /* nav */nav 57 | ]; 58 | 59 | function Header(Props) { 60 | var siteTitle = Props.siteTitle; 61 | return React.createElement("header", { 62 | className: header 63 | }, React.createElement("div", { 64 | className: content 65 | }, React.createElement("h1", { 66 | className: h1 67 | }, React.createElement(Gatsby.Link, { 68 | to: "/", 69 | className: link, 70 | children: siteTitle 71 | })), React.createElement("nav", { 72 | className: nav 73 | }, React.createElement(Gatsby.Link, { 74 | to: "/blog", 75 | className: link, 76 | children: "Blog" 77 | })))); 78 | } 79 | 80 | var make = Header; 81 | 82 | var $$default = Header; 83 | 84 | exports.Styles = Styles; 85 | exports.make = make; 86 | exports.$$default = $$default; 87 | exports.default = $$default; 88 | exports.__esModule = true; 89 | /* header Not a pure module */ 90 | --------------------------------------------------------------------------------