Initial commit
No files matched your search
@@ -0,0 +1 @@
|
||||
Last 2 versions
|
||||
@@ -0,0 +1,20 @@
|
||||
engines:
|
||||
eslint:
|
||||
enabled: true
|
||||
stylelint:
|
||||
enabled: true
|
||||
duplication:
|
||||
enabled: true
|
||||
config:
|
||||
languages:
|
||||
javascript:
|
||||
mass_threshold: 70
|
||||
|
||||
ratings:
|
||||
paths:
|
||||
- "**.js"
|
||||
- "**.jsx"
|
||||
- "**.css"
|
||||
|
||||
exclude_paths:
|
||||
- static/**/*
|
||||
@@ -0,0 +1,4 @@
|
||||
public
|
||||
static
|
||||
.cache
|
||||
content
|
||||
@@ -0,0 +1,17 @@
|
||||
{
|
||||
"extends": ["airbnb", "prettier"],
|
||||
"plugins": ["react", "jsx-a11y", "import"],
|
||||
"rules": {
|
||||
"react/jsx-filename-extension": [1, { "extensions": [".js", ".jsx"] }],
|
||||
"react/prefer-stateless-function": "off",
|
||||
"react/require-default-props": "off",
|
||||
"react/prop-types": "off",
|
||||
"react/no-danger": "off"
|
||||
},
|
||||
"settings": {
|
||||
"import/core-modules": []
|
||||
},
|
||||
"env": {
|
||||
"browser": true
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
# Project dependencies
|
||||
# https://www.npmjs.org/doc/misc/npm-faq.html#should-i-check-my-node_modules-folder-into-git
|
||||
node_modules
|
||||
.cache/
|
||||
# Build directory
|
||||
public/
|
||||
static/admin/*.bundle.*
|
||||
.DS_Store
|
||||
yarn-error.log
|
||||
@@ -0,0 +1,6 @@
|
||||
{
|
||||
"extends": "stylelint-config-standard",
|
||||
"rules": {
|
||||
"indentation": 4
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2015 gatsbyjs
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
|
||||
@@ -0,0 +1,41 @@
|
||||
# Gatsby v2 WordPress Starter
|
||||
|
||||
This starter is forked from the
|
||||
[gatsby-starter-netlify-cms](https://github.com/netlify-templates/gatsby-starter-netlify-cms)
|
||||
and modified to use WordPress instead of netlify-cms.
|
||||
|
||||
Demo: https://gatsby-starter-wordpress.netlify.com/
|
||||
|
||||
> **WARNING**: Using `yarn upgrade` or `npm update` will break the site. See [GatsbyCentral/gatsby-starter-wordpress#36](https://github.com/GatsbyCentral/gatsby-starter-wordpress/issues/36) and [gatsbyjs/gatsby#10262](https://github.com/gatsbyjs/gatsby/issues/10262) for more info. Hopefully we'll have a resolution soon. - 19 Dec 2018
|
||||
|
||||
## Use it now
|
||||
|
||||
gatsby new NAME https://github.com/GatsbyCentral/gatsby-starter-wordpress
|
||||
|
||||
* Edit `gatsby-config.js`, change `baseUrl`
|
||||
- Make sure you have at least 1 post and 1 page on your WordPress site
|
||||
- Make sure at least 1 post has at least 1 tag
|
||||
* Rejoice
|
||||
- File any [issues here](https://github.com/GatsbyCentral/gatsby-starter-wordpress/issues)
|
||||
|
||||
### Known Limitations
|
||||
|
||||
* This is based on the [netlify starter](https://github.com/netlify-templates/gatsby-starter-netlify-cms) which uses [bulma](https://bulma.io). This adds 150KB to every built page.
|
||||
* Your WordPress site must have at least 1 post with 1 tag, or the starter will crash
|
||||
* Nested pages / categories will not render with nested pages
|
||||
- A WordPress page like `/about/team/` will render on Gatsby as `/team/`
|
||||
- Likewise for categories
|
||||
- Discussion here https://github.com/GatsbyCentral/gatsby-starter-wordpress/issues/24
|
||||
|
||||
## CSS Processing
|
||||
|
||||
This plugin uses [gatsby-plugin-purgecss](https://www.gatsbyjs.org/packages/gatsby-plugin-purgecss/) and [bulma](https://bulma.io/). The bulma build would otherwise be ~170K which adds 170K to each of your built HTML pages. However, with purgecss this is reduced 90%.
|
||||
|
||||
## Contributors
|
||||
|
||||
This starter was forked from the netlify starter by the
|
||||
[GatsbyCentral](https://www.gatsbycentral.com/) crew. Additional contributions
|
||||
were gratefully received from the following folks:
|
||||
|
||||
* https://github.com/tomByrer
|
||||
* https://github.com/dajocarter
|
||||
@@ -0,0 +1,29 @@
|
||||
module.exports = {
|
||||
siteMetadata: {
|
||||
title: 'Det Norske Studentersamfund',
|
||||
},
|
||||
plugins: [
|
||||
'gatsby-plugin-react-helmet',
|
||||
'gatsby-plugin-sass',
|
||||
{
|
||||
resolve: 'gatsby-source-wordpress',
|
||||
options: {
|
||||
// The base url to your WP site.
|
||||
baseUrl: 'studentersamfundet.no',
|
||||
// WP.com sites set to true, WP.org set to false
|
||||
hostingWPCOM: false,
|
||||
// The protocol. This can be http or https.
|
||||
protocol: 'https',
|
||||
// Use 'Advanced Custom Fields' Wordpress plugin
|
||||
useACF: false,
|
||||
auth: {},
|
||||
// Set to true to debug endpoints on 'gatsby build'
|
||||
verboseOutput: true,
|
||||
},
|
||||
},
|
||||
'gatsby-plugin-sharp',
|
||||
'gatsby-transformer-sharp',
|
||||
'gatsby-plugin-purgecss',
|
||||
'gatsby-plugin-netlify', // make sure to keep it last in the array
|
||||
],
|
||||
}
|
||||
@@ -0,0 +1,222 @@
|
||||
const _ = require('lodash')
|
||||
const path = require('path')
|
||||
const { createFilePath } = require('gatsby-source-filesystem')
|
||||
const { paginate } = require('gatsby-awesome-pagination')
|
||||
|
||||
const getOnlyPublished = edges =>
|
||||
_.filter(edges, ({ node }) => node.status === 'publish')
|
||||
|
||||
exports.createPages = ({ actions, graphql }) => {
|
||||
const { createPage } = actions
|
||||
|
||||
return graphql(`
|
||||
{
|
||||
allWordpressPage {
|
||||
edges {
|
||||
node {
|
||||
id
|
||||
slug
|
||||
status
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
`)
|
||||
.then(result => {
|
||||
if (result.errors) {
|
||||
result.errors.forEach(e => console.error(e.toString()))
|
||||
return Promise.reject(result.errors)
|
||||
}
|
||||
|
||||
const pageTemplate = path.resolve(`./src/templates/page.js`)
|
||||
|
||||
// Only publish pages with a `status === 'publish'` in production. This
|
||||
// excludes drafts, future posts, etc. They will appear in development,
|
||||
// but not in a production build.
|
||||
|
||||
const allPages = result.data.allWordpressPage.edges
|
||||
const pages =
|
||||
process.env.NODE_ENV === 'production'
|
||||
? getOnlyPublished(allPages)
|
||||
: allPages
|
||||
|
||||
// Call `createPage()` once per WordPress page
|
||||
_.each(pages, ({ node: page }) => {
|
||||
createPage({
|
||||
path: `/${page.slug}/`,
|
||||
component: pageTemplate,
|
||||
context: {
|
||||
id: page.id,
|
||||
},
|
||||
})
|
||||
})
|
||||
})
|
||||
.then(() => {
|
||||
return graphql(`
|
||||
{
|
||||
allWordpressPost {
|
||||
edges {
|
||||
node {
|
||||
id
|
||||
slug
|
||||
status
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
`)
|
||||
})
|
||||
.then(result => {
|
||||
if (result.errors) {
|
||||
result.errors.forEach(e => console.error(e.toString()))
|
||||
return Promise.reject(result.errors)
|
||||
}
|
||||
|
||||
const postTemplate = path.resolve(`./src/templates/post.js`)
|
||||
const blogTemplate = path.resolve(`./src/templates/blog.js`)
|
||||
|
||||
// In production builds, filter for only published posts.
|
||||
const allPosts = result.data.allWordpressPost.edges
|
||||
const posts =
|
||||
process.env.NODE_ENV === 'production'
|
||||
? getOnlyPublished(allPosts)
|
||||
: allPosts
|
||||
|
||||
// Iterate over the array of posts
|
||||
_.each(posts, ({ node: post }) => {
|
||||
// Create the Gatsby page for this WordPress post
|
||||
createPage({
|
||||
path: `/${post.slug}/`,
|
||||
component: postTemplate,
|
||||
context: {
|
||||
id: post.id,
|
||||
},
|
||||
})
|
||||
})
|
||||
|
||||
// Create a paginated blog, e.g., /, /page/2, /page/3
|
||||
paginate({
|
||||
createPage,
|
||||
items: posts,
|
||||
itemsPerPage: 10,
|
||||
pathPrefix: ({ pageNumber }) => (pageNumber === 0 ? `/` : `/page`),
|
||||
component: blogTemplate,
|
||||
})
|
||||
})
|
||||
.then(() => {
|
||||
return graphql(`
|
||||
{
|
||||
allWordpressCategory(filter: { count: { gt: 0 } }) {
|
||||
edges {
|
||||
node {
|
||||
id
|
||||
name
|
||||
slug
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
`)
|
||||
})
|
||||
.then(result => {
|
||||
if (result.errors) {
|
||||
result.errors.forEach(e => console.error(e.toString()))
|
||||
return Promise.reject(result.errors)
|
||||
}
|
||||
|
||||
const categoriesTemplate = path.resolve(`./src/templates/category.js`)
|
||||
|
||||
// Create a Gatsby page for each WordPress Category
|
||||
_.each(result.data.allWordpressCategory.edges, ({ node: cat }) => {
|
||||
createPage({
|
||||
path: `/categories/${cat.slug}/`,
|
||||
component: categoriesTemplate,
|
||||
context: {
|
||||
name: cat.name,
|
||||
slug: cat.slug,
|
||||
},
|
||||
})
|
||||
})
|
||||
})
|
||||
.then(() => {
|
||||
return graphql(`
|
||||
{
|
||||
allWordpressTag(filter: { count: { gt: 0 } }) {
|
||||
edges {
|
||||
node {
|
||||
id
|
||||
name
|
||||
slug
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
`)
|
||||
})
|
||||
|
||||
.then(result => {
|
||||
if (result.errors) {
|
||||
result.errors.forEach(e => console.error(e.toString()))
|
||||
return Promise.reject(result.errors)
|
||||
}
|
||||
|
||||
const tagsTemplate = path.resolve(`./src/templates/tag.js`)
|
||||
|
||||
// Create a Gatsby page for each WordPress tag
|
||||
_.each(result.data.allWordpressTag.edges, ({ node: tag }) => {
|
||||
createPage({
|
||||
path: `/tags/${tag.slug}/`,
|
||||
component: tagsTemplate,
|
||||
context: {
|
||||
name: tag.name,
|
||||
slug: tag.slug,
|
||||
},
|
||||
})
|
||||
})
|
||||
})
|
||||
.then(() => {
|
||||
return graphql(`
|
||||
{
|
||||
allWordpressWpUsers {
|
||||
edges {
|
||||
node {
|
||||
id
|
||||
slug
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
`)
|
||||
})
|
||||
.then(result => {
|
||||
if (result.errors) {
|
||||
result.errors.forEach(e => console.error(e.toString()))
|
||||
return Promise.reject(result.errors)
|
||||
}
|
||||
|
||||
const authorTemplate = path.resolve(`./src/templates/author.js`)
|
||||
|
||||
_.each(result.data.allWordpressWpUsers.edges, ({ node: author }) => {
|
||||
createPage({
|
||||
path: `/author/${author.slug}`,
|
||||
component: authorTemplate,
|
||||
context: {
|
||||
id: author.id,
|
||||
},
|
||||
})
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
exports.onCreateNode = ({ node, actions, getNode }) => {
|
||||
const { createNodeField } = actions
|
||||
|
||||
if (node.internal.type === `MarkdownRemark`) {
|
||||
const value = createFilePath({ node, getNode })
|
||||
createNodeField({
|
||||
name: `slug`,
|
||||
node,
|
||||
value,
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
[build]
|
||||
publish = "public"
|
||||
command = "npm run build"
|
||||
[build.environment]
|
||||
YARN_VERSION = "1.3.2"
|
||||
YARN_FLAGS = "--no-ignore-optional"
|
||||
@@ -0,0 +1,55 @@
|
||||
{
|
||||
"name": "gatsby-starter-wordpress",
|
||||
"description": "Gatsby v2 starter for WordPress",
|
||||
"version": "0.1.0",
|
||||
"author": "GatsbyCentral.com",
|
||||
"dependencies": {
|
||||
"bulma": "^0.7.0",
|
||||
"gatsby": "^2.0.0",
|
||||
"gatsby-awesome-pagination": "^0.3.3",
|
||||
"gatsby-plugin-lodash": "^3.0.1",
|
||||
"gatsby-plugin-netlify": "^2.0.0",
|
||||
"gatsby-plugin-purgecss": "^2.4.0",
|
||||
"gatsby-plugin-react-helmet": "^3.0.0",
|
||||
"gatsby-plugin-sass": "^2.0.1",
|
||||
"gatsby-plugin-sharp": "^2.0.5",
|
||||
"gatsby-remark-images": "^2.0.1",
|
||||
"gatsby-source-filesystem": "^2.0.1",
|
||||
"gatsby-source-wordpress": "^3.0.1",
|
||||
"gatsby-transformer-remark": "^2.1.1",
|
||||
"gatsby-transformer-sharp": "^2.1.1",
|
||||
"lodash": "^4.17.5",
|
||||
"node-sass": "^4.9.2",
|
||||
"parcel-bundler": "^1.9.4",
|
||||
"prop-types": "^15.6.0",
|
||||
"react": "^16.2.0",
|
||||
"react-dom": "^16.4.1",
|
||||
"react-helmet": "^5.2.0",
|
||||
"uuid": "^3.2.1"
|
||||
},
|
||||
"keywords": [
|
||||
"gatsby"
|
||||
],
|
||||
"license": "MIT",
|
||||
"main": "n/a",
|
||||
"scripts": {
|
||||
"start": "npm run develop",
|
||||
"clean": "rimraf .cache public",
|
||||
"build": "npm run clean && gatsby build",
|
||||
"develop": "npm run clean && gatsby develop",
|
||||
"serve": "gatsby serve",
|
||||
"format": "prettier --trailing-comma es5 --no-semi --single-quote --write \"{gatsby-*.js,src/**/*.js}\"",
|
||||
"test": "echo \"Error: no test specified\" && exit 1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"eslint-config-airbnb": "^17.1.0",
|
||||
"eslint-config-prettier": "^3.1.0",
|
||||
"prettier": "^1.7.4",
|
||||
"rimraf": "^2.6.2"
|
||||
},
|
||||
"prettier": {
|
||||
"trailingComma": "es5",
|
||||
"semi": false,
|
||||
"singleQuote": true
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
{
|
||||
"extends": [
|
||||
"config:base"
|
||||
],
|
||||
"rangeStrategy": "replace",
|
||||
"lockFileMaintenance": {
|
||||
"enabled": true,
|
||||
"extends": "schedule:weekly"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
import React from 'react'
|
||||
import PropTypes from 'prop-types'
|
||||
|
||||
export const HTMLContent = ({ content, className }) => (
|
||||
<div className={className} dangerouslySetInnerHTML={{ __html: content }} />
|
||||
)
|
||||
|
||||
const Content = ({ content, className }) => (
|
||||
<div className={className}>{content}</div>
|
||||
)
|
||||
|
||||
Content.propTypes = {
|
||||
content: PropTypes.node,
|
||||
className: PropTypes.string,
|
||||
}
|
||||
|
||||
HTMLContent.propTypes = Content.propTypes
|
||||
|
||||
export default Content
|
||||
@@ -0,0 +1,28 @@
|
||||
import React from 'react'
|
||||
import PropTypes from 'prop-types'
|
||||
|
||||
const FeatureGrid = ({ gridItems }) => (
|
||||
<div className="columns is-multiline">
|
||||
{gridItems.map(item => (
|
||||
<div key={item.image} className="column is-6">
|
||||
<section className="section">
|
||||
<p className="has-text-centered">
|
||||
<img alt="" src={item.image} />
|
||||
</p>
|
||||
<p>{item.text}</p>
|
||||
</section>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
)
|
||||
|
||||
FeatureGrid.propTypes = {
|
||||
gridItems: PropTypes.arrayOf(
|
||||
PropTypes.shape({
|
||||
image: PropTypes.string,
|
||||
text: PropTypes.string,
|
||||
})
|
||||
),
|
||||
}
|
||||
|
||||
export default FeatureGrid
|
||||
@@ -0,0 +1,15 @@
|
||||
import React from 'react'
|
||||
import Helmet from 'react-helmet'
|
||||
|
||||
import Navbar from './Navbar'
|
||||
import './all.sass'
|
||||
|
||||
const TemplateWrapper = ({ children }) => (
|
||||
<div>
|
||||
<Helmet title="Home | Gatsby + WordPress" />
|
||||
<Navbar />
|
||||
<div>{children}</div>
|
||||
</div>
|
||||
)
|
||||
|
||||
export default TemplateWrapper
|
||||
@@ -0,0 +1,59 @@
|
||||
import React from 'react'
|
||||
import { Link, StaticQuery, graphql } from 'gatsby'
|
||||
import github from '../img/github-icon.svg'
|
||||
import logo from '../img/logo.svg'
|
||||
|
||||
const Navbar = () => (
|
||||
<StaticQuery
|
||||
query={graphql`
|
||||
query {
|
||||
allWordpressPage(sort: { fields: wordpress_id }, limit: 5) {
|
||||
edges {
|
||||
node {
|
||||
title
|
||||
slug
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
`}
|
||||
render={data => (
|
||||
<nav className="navbar is-transparent">
|
||||
<div className="container">
|
||||
<div className="navbar-brand">
|
||||
<Link to="/" className="navbar-item">
|
||||
<figure className="image">
|
||||
<img src={logo} alt="Kaldi" style={{ width: '88px' }} />
|
||||
</figure>
|
||||
</Link>
|
||||
</div>
|
||||
<div className="navbar-start">
|
||||
{data.allWordpressPage.edges.map(edge => (
|
||||
<Link
|
||||
className="navbar-item"
|
||||
to={edge.node.slug}
|
||||
key={edge.node.slug}
|
||||
>
|
||||
{edge.node.title}
|
||||
</Link>
|
||||
))}
|
||||
</div>
|
||||
<div className="navbar-end">
|
||||
<a
|
||||
className="navbar-item"
|
||||
href="https://github.com/GatsbyCentral/gatsby-starter-wordpress"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
>
|
||||
<span className="icon">
|
||||
<img src={github} alt="Github" />
|
||||
</span>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</nav>
|
||||
)}
|
||||
/>
|
||||
)
|
||||
|
||||
export default Navbar
|
||||
@@ -0,0 +1,29 @@
|
||||
import React from 'react'
|
||||
import { Link } from 'gatsby'
|
||||
|
||||
const Pagination = ({ pageContext, pathPrefix }) => {
|
||||
const { previousPagePath, nextPagePath } = pageContext
|
||||
|
||||
return (
|
||||
<nav className="pagination" role="navigation">
|
||||
<div className="navbar navbar-menu">
|
||||
{previousPagePath && (
|
||||
<div className="navbar-item">
|
||||
<Link to={previousPagePath} rel="prev">
|
||||
Previous
|
||||
</Link>
|
||||
</div>
|
||||
)}
|
||||
{nextPagePath && (
|
||||
<div className="navbar-item">
|
||||
<Link to={nextPagePath} rel="next">
|
||||
Next
|
||||
</Link>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</nav>
|
||||
)
|
||||
}
|
||||
|
||||
export default Pagination
|
||||
@@ -0,0 +1,71 @@
|
||||
import React from 'react'
|
||||
import PropTypes from 'prop-types'
|
||||
import { Link, graphql } from 'gatsby'
|
||||
|
||||
export default class IndexPage extends React.Component {
|
||||
render() {
|
||||
const { posts, title } = this.props
|
||||
|
||||
return (
|
||||
<section className="section">
|
||||
<div className="container">
|
||||
<div className="content">
|
||||
<h1 className="has-text-weight-bold is-size-2">{title}</h1>
|
||||
</div>
|
||||
{posts.map(({ node: post }) => (
|
||||
<div
|
||||
className="content"
|
||||
style={{ border: '1px solid #eaecee', padding: '2em 4em' }}
|
||||
key={post.id}
|
||||
>
|
||||
<p>
|
||||
<Link className="has-text-primary" to={post.slug}>
|
||||
{post.title}
|
||||
</Link>
|
||||
<span> • </span>
|
||||
<small>
|
||||
{post.date} - posted by{' '}
|
||||
<Link to={`/author/${post.author.slug}`}>
|
||||
{post.author.name}
|
||||
</Link>
|
||||
</small>
|
||||
</p>
|
||||
<div>
|
||||
<div
|
||||
dangerouslySetInnerHTML={{
|
||||
__html: post.excerpt.replace(/<p class="link-more.*/, ''),
|
||||
}}
|
||||
/>
|
||||
<Link className="button is-small" to={post.slug}>
|
||||
Keep Reading →
|
||||
</Link>
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</section>
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
IndexPage.propTypes = {
|
||||
posts: PropTypes.arrayOf(PropTypes.object),
|
||||
title: PropTypes.string,
|
||||
}
|
||||
|
||||
export const pageQuery = graphql`
|
||||
fragment PostListFields on wordpress__POST {
|
||||
id
|
||||
title
|
||||
excerpt
|
||||
author {
|
||||
name
|
||||
slug
|
||||
avatar_urls {
|
||||
wordpress_48
|
||||
}
|
||||
}
|
||||
date(formatString: "MMMM DD, YYYY")
|
||||
slug
|
||||
}
|
||||
`
|
||||
@@ -0,0 +1,40 @@
|
||||
import React from 'react'
|
||||
import PropTypes from 'prop-types'
|
||||
|
||||
const Pricing = ({ data }) => (
|
||||
<div className="columns">
|
||||
{data.map(price => (
|
||||
<div key={price.plan} className="column">
|
||||
<section className="section">
|
||||
<h4 className="has-text-centered has-text-weight-semibold">
|
||||
{price.plan}
|
||||
</h4>
|
||||
<h2 className="is-size-1 has-text-weight-bold has-text-primary has-text-centered">
|
||||
${price.price}
|
||||
</h2>
|
||||
<p className="has-text-weight-semibold">{price.description}</p>
|
||||
<ul>
|
||||
{price.items.map(item => (
|
||||
<li key={item} className="is-size-5">
|
||||
{item}
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
</section>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
)
|
||||
|
||||
Pricing.propTypes = {
|
||||
data: PropTypes.arrayOf(
|
||||
PropTypes.shape({
|
||||
plan: PropTypes.string,
|
||||
price: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),
|
||||
description: PropTypes.string,
|
||||
items: PropTypes.array,
|
||||
})
|
||||
),
|
||||
}
|
||||
|
||||
export default Pricing
|
||||
@@ -0,0 +1,28 @@
|
||||
import React from 'react'
|
||||
import PropTypes from 'prop-types'
|
||||
import { v4 } from 'uuid'
|
||||
|
||||
const Testimonials = ({ testimonials }) => (
|
||||
<div>
|
||||
{testimonials.map(testimonial => (
|
||||
<article key={v4()} className="message">
|
||||
<div className="message-body">
|
||||
{testimonial.quote}
|
||||
<br />
|
||||
<cite> – {testimonial.author}</cite>
|
||||
</div>
|
||||
</article>
|
||||
))}
|
||||
</div>
|
||||
)
|
||||
|
||||
Testimonials.propTypes = {
|
||||
testimonials: PropTypes.arrayOf(
|
||||
PropTypes.shape({
|
||||
quote: PropTypes.string,
|
||||
author: PropTypes.string,
|
||||
})
|
||||
),
|
||||
}
|
||||
|
||||
export default Testimonials
|
||||
@@ -0,0 +1,45 @@
|
||||
@import "~bulma/sass/utilities/initial-variables"
|
||||
|
||||
// Config vars
|
||||
$kaldi-red: #FD461E
|
||||
$kaldi-red-invert: #fff
|
||||
|
||||
$primary: $kaldi-red
|
||||
$primary-invert: $kaldi-red-invert
|
||||
|
||||
.content .taglist
|
||||
list-style: none
|
||||
margin-bottom: 0
|
||||
margin-left: 0
|
||||
margin-right: 1.5rem
|
||||
margin-top: 1.5rem
|
||||
display: flex
|
||||
flex-wrap: wrap
|
||||
justify-content: left
|
||||
align-items: center
|
||||
li
|
||||
padding: 0 2rem 1rem 0
|
||||
margin-bottom: 1.5rem
|
||||
margin-top: 0
|
||||
|
||||
.pagination .navbar
|
||||
justify-content: center
|
||||
|
||||
// Helper Classes
|
||||
.full-width-image-container
|
||||
width: 100vw
|
||||
height: 400px
|
||||
position: relative
|
||||
left: 50%
|
||||
right: 50%
|
||||
margin: 5em -50vw
|
||||
background-size: cover
|
||||
background-position: bottom
|
||||
display: flex
|
||||
justify-content: center
|
||||
align-items: center
|
||||
|
||||
.margin-top-0
|
||||
margin-top: 0 !important
|
||||
|
||||
@import "~bulma"
|
||||
@@ -0,0 +1,5 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" id="Capa_1" x="0px" y="0px" width="438.549px" height="438.549px" viewBox="0 0 438.549 438.549" style="enable-background:new 0 0 438.549 438.549;" xml:space="preserve">
|
||||
<g>
|
||||
<path d="M409.132,114.573c-19.608-33.596-46.205-60.194-79.798-79.8C295.736,15.166,259.057,5.365,219.271,5.365 c-39.781,0-76.472,9.804-110.063,29.408c-33.596,19.605-60.192,46.204-79.8,79.8C9.803,148.168,0,184.854,0,224.63 c0,47.78,13.94,90.745,41.827,128.906c27.884,38.164,63.906,64.572,108.063,79.227c5.14,0.954,8.945,0.283,11.419-1.996 c2.475-2.282,3.711-5.14,3.711-8.562c0-0.571-0.049-5.708-0.144-15.417c-0.098-9.709-0.144-18.179-0.144-25.406l-6.567,1.136 c-4.187,0.767-9.469,1.092-15.846,1c-6.374-0.089-12.991-0.757-19.842-1.999c-6.854-1.231-13.229-4.086-19.13-8.559 c-5.898-4.473-10.085-10.328-12.56-17.556l-2.855-6.57c-1.903-4.374-4.899-9.233-8.992-14.559 c-4.093-5.331-8.232-8.945-12.419-10.848l-1.999-1.431c-1.332-0.951-2.568-2.098-3.711-3.429c-1.142-1.331-1.997-2.663-2.568-3.997 c-0.572-1.335-0.098-2.43,1.427-3.289c1.525-0.859,4.281-1.276,8.28-1.276l5.708,0.853c3.807,0.763,8.516,3.042,14.133,6.851 c5.614,3.806,10.229,8.754,13.846,14.842c4.38,7.806,9.657,13.754,15.846,17.847c6.184,4.093,12.419,6.136,18.699,6.136 c6.28,0,11.704-0.476,16.274-1.423c4.565-0.952,8.848-2.383,12.847-4.285c1.713-12.758,6.377-22.559,13.988-29.41 c-10.848-1.14-20.601-2.857-29.264-5.14c-8.658-2.286-17.605-5.996-26.835-11.14c-9.235-5.137-16.896-11.516-22.985-19.126 c-6.09-7.614-11.088-17.61-14.987-29.979c-3.901-12.374-5.852-26.648-5.852-42.826c0-23.035,7.52-42.637,22.557-58.817 c-7.044-17.318-6.379-36.732,1.997-58.24c5.52-1.715,13.706-0.428,24.554,3.853c10.85,4.283,18.794,7.952,23.84,10.994 c5.046,3.041,9.089,5.618,12.135,7.708c17.705-4.947,35.976-7.421,54.818-7.421s37.117,2.474,54.823,7.421l10.849-6.849 c7.419-4.57,16.18-8.758,26.262-12.565c10.088-3.805,17.802-4.853,23.134-3.138c8.562,21.509,9.325,40.922,2.279,58.24 c15.036,16.18,22.559,35.787,22.559,58.817c0,16.178-1.958,30.497-5.853,42.966c-3.9,12.471-8.941,22.457-15.125,29.979 c-6.191,7.521-13.901,13.85-23.131,18.986c-9.232,5.14-18.182,8.85-26.84,11.136c-8.662,2.286-18.415,4.004-29.263,5.146 c9.894,8.562,14.842,22.077,14.842,40.539v60.237c0,3.422,1.19,6.279,3.572,8.562c2.379,2.279,6.136,2.95,11.276,1.995 c44.163-14.653,80.185-41.062,108.068-79.226c27.88-38.161,41.825-81.126,41.825-128.906 C438.536,184.851,428.728,148.168,409.132,114.573z"/>
|
||||
</g>
|
||||
<div xmlns="" id="divScriptsUsed" style="display: none"/><script xmlns="" id="globalVarsDetection" src="chrome-extension://cmkdbmfndkfgebldhnkbfhlneefdaaip/js/wrs_env.js"/></svg>
|
||||
|
After Width: | Height: | Size: 2.6 KiB |
@@ -0,0 +1 @@
|
||||
<svg viewBox="0 0 109 24" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:figma="http://www.figma.com/figma/ns"><title>Logo</title><g transform="translate(-1470)" figma:type="canvas"><g style="mix-blend-mode:normal" figma:type="vector" transform="translate(1470)" fill="#f40"><use xlink:href="#b" style="mix-blend-mode:normal"/><use xlink:href="#c" style="mix-blend-mode:normal"/><use xlink:href="#d" style="mix-blend-mode:normal"/><use xlink:href="#e" style="mix-blend-mode:normal"/><use xlink:href="#f" style="mix-blend-mode:normal"/></g></g><defs><path id="b" d="M22.735 23.171c.283.323.053.829-.376.829h-5.907c-.285 0-.556-.121-.745-.333l-9.414-10.526v10.36c0 .276-.224.5-.5.5h-5.293c-.276 0-.5-.224-.5-.5v-23c0-.276.224-.5.5-.5h5.293c.276 0 .5.224.5.5v9.815l9.141-9.99c.19-.207.457-.325.738-.325h5.762c.437 0 .664.521.366.841l-9.851 10.563 10.287 11.767z"/><path id="c" d="M45.991 24c-.199 0-.38-.118-.459-.301l-2.024-4.669h-10.67l-2.024 4.669c-.079.183-.259.301-.459.301h-5.212c-.366 0-.608-.381-.453-.712l10.782-23c.082-.176.259-.288.453-.288h4.358c.194 0 .37.112.453.287l10.815 23c.156.332-.086.713-.452.713h-5.108zm-11.135-9.668h6.635l-3.317-7.694-3.317 7.694z"/><path id="d" d="M55.525 24c-.276 0-.5-.224-.5-.5v-23c0-.276.224-.5.5-.5h5.293c.276 0 .5.224.5.5v18.428h9.759c.276 0 .5.224.5.5v4.072c0 .276-.224.5-.5.5h-15.552z"/><path id="e" d="M75.279.5c0-.276.224-.5.5-.5h9.315c2.667 0 4.959.477 6.874 1.43 1.938.953 3.42 2.338 4.446 4.153 1.026 1.793 1.539 3.926 1.539 6.4 0 2.496-.513 4.652-1.539 6.468-1.003 1.793-2.474 3.166-4.412 4.119-1.915.953-4.218 1.43-6.908 1.43h-9.315c-.276 0-.5-.224-.5-.5v-23zm9.37 18.462c2.371 0 4.138-.579 5.301-1.736 1.163-1.157 1.744-2.905 1.744-5.242 0-2.338-.581-4.074-1.744-5.209-1.163-1.157-2.93-1.736-5.301-1.736h-3.078v13.923h3.078z"/><path id="f" d="M102.913 24c-.276 0-.5-.224-.5-.5v-23c0-.276.224-.5.5-.5h5.293c.276 0 .5.224.5.5v23c0 .276-.224.5-.5.5h-5.293z"/></defs></svg>
|
||||
|
After Width: | Height: | Size: 1.9 KiB |
@@ -0,0 +1,13 @@
|
||||
import React from 'react'
|
||||
import Layout from '../components/Layout'
|
||||
|
||||
const NotFoundPage = () => (
|
||||
<Layout>
|
||||
<div>
|
||||
<h1>NOT FOUND</h1>
|
||||
<p>You just hit a route that doesn't exist... the sadness.</p>
|
||||
</div>
|
||||
</Layout>
|
||||
)
|
||||
|
||||
export default NotFoundPage
|
||||
@@ -0,0 +1,46 @@
|
||||
import React from 'react'
|
||||
import Helmet from 'react-helmet'
|
||||
import { graphql } from 'gatsby'
|
||||
import Layout from '../components/Layout'
|
||||
import PostList from '../components/PostList'
|
||||
|
||||
const Author = props => {
|
||||
const { data } = props
|
||||
console.log(data.wordpressWpUsers)
|
||||
const { authored_wordpress__POST, name } = data.wordpressWpUsers
|
||||
const totalCount =
|
||||
(authored_wordpress__POST && authored_wordpress__POST.length) || 0
|
||||
const { title: siteTitle } = data.site.siteMetadata
|
||||
const title = `${totalCount} post${totalCount === 1 ? '' : 's'} by ${name}`
|
||||
|
||||
// The `authored_wordpress__POST` returns a simple array instead of an array
|
||||
// of edges / nodes. We therefore need to convert the array here.
|
||||
const posts = authored_wordpress__POST.map(post => ({
|
||||
node: post,
|
||||
}))
|
||||
|
||||
return (
|
||||
<Layout>
|
||||
<Helmet title={`${name} | ${siteTitle}`} />
|
||||
<PostList posts={posts} title={title} />
|
||||
</Layout>
|
||||
)
|
||||
}
|
||||
|
||||
export default Author
|
||||
|
||||
export const pageQuery = graphql`
|
||||
query AuthorPage($id: String!) {
|
||||
site {
|
||||
siteMetadata {
|
||||
title
|
||||
}
|
||||
}
|
||||
wordpressWpUsers(id: { eq: $id }) {
|
||||
name
|
||||
authored_wordpress__POST {
|
||||
...PostListFields
|
||||
}
|
||||
}
|
||||
}
|
||||
`
|
||||
@@ -0,0 +1,48 @@
|
||||
import React from 'react'
|
||||
import PropTypes from 'prop-types'
|
||||
import { graphql } from 'gatsby'
|
||||
import Layout from '../components/Layout'
|
||||
import PostList from '../components/PostList'
|
||||
import Pagination from '../components/Pagination'
|
||||
|
||||
export default class IndexPage extends React.Component {
|
||||
render() {
|
||||
const { data, pageContext } = this.props
|
||||
const { edges: posts } = data.allWordpressPost
|
||||
|
||||
return (
|
||||
<Layout>
|
||||
<PostList posts={posts} title="Latest posts" />
|
||||
<Pagination pageContext={pageContext} pathPrefix="/" />
|
||||
</Layout>
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
IndexPage.propTypes = {
|
||||
data: PropTypes.shape({
|
||||
allWordpressPost: PropTypes.shape({
|
||||
edges: PropTypes.array,
|
||||
}),
|
||||
}),
|
||||
pageContext: PropTypes.shape({
|
||||
currentPage: PropTypes.number,
|
||||
numPages: PropTypes.number,
|
||||
}),
|
||||
}
|
||||
|
||||
export const pageQuery = graphql`
|
||||
query IndexQuery($limit: Int!, $skip: Int!) {
|
||||
allWordpressPost(
|
||||
sort: { fields: date, order: DESC }
|
||||
limit: $limit
|
||||
skip: $skip
|
||||
) {
|
||||
edges {
|
||||
node {
|
||||
...PostListFields
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
`
|
||||
@@ -0,0 +1,42 @@
|
||||
import React from 'react'
|
||||
import Helmet from 'react-helmet'
|
||||
import { graphql } from 'gatsby'
|
||||
import Layout from '../components/Layout'
|
||||
import PostList from '../components/PostList'
|
||||
|
||||
const Category = props => {
|
||||
const { data, pageContext } = props
|
||||
const { edges: posts, totalCount } = data.allWordpressPost
|
||||
const { title: siteTitle } = data.site.siteMetadata
|
||||
const { name: category } = pageContext
|
||||
const title = `${totalCount} post${
|
||||
totalCount === 1 ? '' : 's'
|
||||
} in the “${category}” category`
|
||||
|
||||
return (
|
||||
<Layout>
|
||||
<Helmet title={`${category} | ${siteTitle}`} />
|
||||
<PostList posts={posts} title={title} />
|
||||
</Layout>
|
||||
)
|
||||
}
|
||||
|
||||
export default Category
|
||||
|
||||
export const pageQuery = graphql`
|
||||
query CategoryPage($slug: String!) {
|
||||
site {
|
||||
siteMetadata {
|
||||
title
|
||||
}
|
||||
}
|
||||
allWordpressPost(filter: { categories: { slug: { eq: $slug } } }) {
|
||||
totalCount
|
||||
edges {
|
||||
node {
|
||||
...PostListFields
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
`
|
||||
@@ -0,0 +1,56 @@
|
||||
import React from 'react'
|
||||
import PropTypes from 'prop-types'
|
||||
import { graphql } from 'gatsby'
|
||||
import Layout from '../components/Layout'
|
||||
|
||||
export const PageTemplate = ({ title, content }) => {
|
||||
return (
|
||||
<section className="section section--gradient">
|
||||
<div className="container">
|
||||
<div className="columns">
|
||||
<div className="column is-10 is-offset-1">
|
||||
<div className="section">
|
||||
<h2 className="title is-size-3 has-text-weight-bold is-bold-light">
|
||||
{title}
|
||||
</h2>
|
||||
<div
|
||||
className="content"
|
||||
dangerouslySetInnerHTML={{ __html: content }}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
)
|
||||
}
|
||||
|
||||
PageTemplate.propTypes = {
|
||||
title: PropTypes.string.isRequired,
|
||||
content: PropTypes.string,
|
||||
}
|
||||
|
||||
const Page = ({ data }) => {
|
||||
const { wordpressPage: page } = data
|
||||
|
||||
return (
|
||||
<Layout>
|
||||
<PageTemplate title={page.title} content={page.content} />
|
||||
</Layout>
|
||||
)
|
||||
}
|
||||
|
||||
Page.propTypes = {
|
||||
data: PropTypes.object.isRequired,
|
||||
}
|
||||
|
||||
export default Page
|
||||
|
||||
export const pageQuery = graphql`
|
||||
query PageById($id: String!) {
|
||||
wordpressPage(id: { eq: $id }) {
|
||||
title
|
||||
content
|
||||
}
|
||||
}
|
||||
`
|
||||
@@ -0,0 +1,123 @@
|
||||
import React from 'react'
|
||||
import PropTypes from 'prop-types'
|
||||
import Helmet from 'react-helmet'
|
||||
import { graphql, Link } from 'gatsby'
|
||||
import Layout from '../components/Layout'
|
||||
|
||||
export const BlogPostTemplate = ({
|
||||
content,
|
||||
categories,
|
||||
tags,
|
||||
title,
|
||||
date,
|
||||
author,
|
||||
}) => {
|
||||
return (
|
||||
<section className="section">
|
||||
<div className="container content">
|
||||
<div className="columns">
|
||||
<div className="column is-10 is-offset-1">
|
||||
<h1 className="title is-size-2 has-text-weight-bold is-bold-light">
|
||||
{title}
|
||||
</h1>
|
||||
<div dangerouslySetInnerHTML={{ __html: content }} />
|
||||
<div style={{ marginTop: `4rem` }}>
|
||||
<p>
|
||||
{date} - posted by{' '}
|
||||
<Link to={`/author/${author.slug}`}>{author.name}</Link>
|
||||
</p>
|
||||
{categories && categories.length ? (
|
||||
<div>
|
||||
<h4>Categories</h4>
|
||||
<ul className="taglist">
|
||||
{categories.map(category => (
|
||||
<li key={`${category.slug}cat`}>
|
||||
<Link to={`/categories/${category.slug}/`}>
|
||||
{category.name}
|
||||
</Link>
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
</div>
|
||||
) : null}
|
||||
{tags && tags.length ? (
|
||||
<div>
|
||||
<h4>Tags</h4>
|
||||
<ul className="taglist">
|
||||
{tags.map(tag => (
|
||||
<li key={`${tag.slug}tag`}>
|
||||
<Link to={`/tags/${tag.slug}/`}>{tag.name}</Link>
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
</div>
|
||||
) : null}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
)
|
||||
}
|
||||
|
||||
BlogPostTemplate.propTypes = {
|
||||
content: PropTypes.node.isRequired,
|
||||
title: PropTypes.string,
|
||||
}
|
||||
|
||||
const BlogPost = ({ data }) => {
|
||||
const { wordpressPost: post } = data
|
||||
|
||||
return (
|
||||
<Layout>
|
||||
<Helmet title={`${post.title} | Blog`} />
|
||||
<BlogPostTemplate
|
||||
content={post.content}
|
||||
categories={post.categories}
|
||||
tags={post.tags}
|
||||
title={post.title}
|
||||
date={post.date}
|
||||
author={post.author}
|
||||
/>
|
||||
</Layout>
|
||||
)
|
||||
}
|
||||
|
||||
BlogPost.propTypes = {
|
||||
data: PropTypes.shape({
|
||||
markdownRemark: PropTypes.object,
|
||||
}),
|
||||
}
|
||||
|
||||
export default BlogPost
|
||||
|
||||
export const pageQuery = graphql`
|
||||
fragment PostFields on wordpress__POST {
|
||||
id
|
||||
slug
|
||||
content
|
||||
date(formatString: "MMMM DD, YYYY")
|
||||
title
|
||||
}
|
||||
query BlogPostByID($id: String!) {
|
||||
wordpressPost(id: { eq: $id }) {
|
||||
id
|
||||
title
|
||||
slug
|
||||
content
|
||||
date(formatString: "MMMM DD, YYYY")
|
||||
categories {
|
||||
name
|
||||
slug
|
||||
}
|
||||
tags {
|
||||
name
|
||||
slug
|
||||
}
|
||||
author {
|
||||
name
|
||||
slug
|
||||
}
|
||||
}
|
||||
}
|
||||
`
|
||||
@@ -0,0 +1,42 @@
|
||||
import React from 'react'
|
||||
import Helmet from 'react-helmet'
|
||||
import { graphql } from 'gatsby'
|
||||
import Layout from '../components/Layout'
|
||||
import PostList from '../components/PostList'
|
||||
|
||||
const Tag = props => {
|
||||
const { data, pageContext } = props
|
||||
const { edges: posts, totalCount } = data.allWordpressPost
|
||||
const { title: siteTitle } = data.site.siteMetadata
|
||||
const { name: tag } = pageContext
|
||||
const title = `${totalCount} post${
|
||||
totalCount === 1 ? '' : 's'
|
||||
} with the tag ${tag}`
|
||||
|
||||
return (
|
||||
<Layout>
|
||||
<Helmet title={`${tag} | ${siteTitle}`} />
|
||||
<PostList posts={posts} title={title} />
|
||||
</Layout>
|
||||
)
|
||||
}
|
||||
|
||||
export default Tag
|
||||
|
||||
export const pageQuery = graphql`
|
||||
query TagPage($slug: String!) {
|
||||
site {
|
||||
siteMetadata {
|
||||
title
|
||||
}
|
||||
}
|
||||
allWordpressPost(filter: { tags: { slug: { eq: $slug } } }) {
|
||||
totalCount
|
||||
edges {
|
||||
node {
|
||||
...PostListFields
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
`
|
||||
|
After Width: | Height: | Size: 143 KiB |
|
After Width: | Height: | Size: 5.2 KiB |
|
After Width: | Height: | Size: 7.5 KiB |
|
After Width: | Height: | Size: 59 KiB |
|
After Width: | Height: | Size: 133 KiB |
|
After Width: | Height: | Size: 6.1 KiB |
|
After Width: | Height: | Size: 212 KiB |
|
After Width: | Height: | Size: 321 KiB |
|
After Width: | Height: | Size: 162 KiB |
|
After Width: | Height: | Size: 146 KiB |
|
After Width: | Height: | Size: 4.2 KiB |