convert website from hugo to gatsby (#1369)
2
.gitignore
vendored
@ -8,5 +8,5 @@ yarn-error.log
|
|||||||
.vscode/
|
.vscode/
|
||||||
manifest.yml
|
manifest.yml
|
||||||
.imdone/
|
.imdone/
|
||||||
website/site/data/contributors.yml
|
website/data/contributors.json
|
||||||
/coverage/
|
/coverage/
|
||||||
|
@ -1,7 +1,4 @@
|
|||||||
{
|
{
|
||||||
"presets": ["es2015"],
|
"presets": ["react", "es2015", "stage-1"],
|
||||||
"plugins": [
|
"plugins": ["add-module-exports"]
|
||||||
"syntax-object-rest-spread",
|
|
||||||
"transform-object-rest-spread"
|
|
||||||
]
|
|
||||||
}
|
}
|
5
website/.eslintrc
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
{
|
||||||
|
"globals": {
|
||||||
|
"graphql": true
|
||||||
|
}
|
||||||
|
}
|
3
website/.gitignore
vendored
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
.cache
|
||||||
|
public
|
||||||
|
dist
|
@ -1 +1 @@
|
|||||||
node
|
8
|
||||||
|
@ -4,7 +4,7 @@ This directory builds netlifycms.org. If you'd like to propose changes to the si
|
|||||||
|
|
||||||
## Local development
|
## Local development
|
||||||
|
|
||||||
The site is built with [Hugo](https://gohugo.io/), managed as an npm dependency via [hugo-bin](https://www.npmjs.com/package/hugo-bin).
|
The site is built with [GatsbyJS](https://gatsbyjs.org/).
|
||||||
|
|
||||||
To run the site locally, you'll need to have [Node](https://nodejs.org) and [Yarn](https://yarnpkg.com/en/) installed on your computer.
|
To run the site locally, you'll need to have [Node](https://nodejs.org) and [Yarn](https://yarnpkg.com/en/) installed on your computer.
|
||||||
|
|
||||||
@ -15,5 +15,5 @@ yarn
|
|||||||
yarn start
|
yarn start
|
||||||
```
|
```
|
||||||
|
|
||||||
Then visit http://localhost:3000/ - BrowserSync will automatically reload CSS or
|
Then visit http://localhost:8000/ - Gatsby will automatically reload CSS or
|
||||||
refresh the page when stylesheets or content changes.
|
refresh the page when stylesheets or content changes.
|
@ -1,13 +1,9 @@
|
|||||||
---
|
---
|
||||||
title: Add to Your Site
|
title: Add to Your Site
|
||||||
weight: 20
|
weight: 20
|
||||||
menu:
|
group: start
|
||||||
docs:
|
|
||||||
parent: start
|
|
||||||
---
|
---
|
||||||
|
|
||||||
# Add Netlify CMS to Your Site
|
|
||||||
|
|
||||||
Netlify CMS is adaptable to a wide variety of projects. It works with any content written in markdown, JSON, YAML, or TOML files, stored in a repo on [GitHub](https://github.com/), [GitLab](https://about.gitlab.com/), or [Bitbucket](https://bitbucket.org). You can also create your own custom backend.
|
Netlify CMS is adaptable to a wide variety of projects. It works with any content written in markdown, JSON, YAML, or TOML files, stored in a repo on [GitHub](https://github.com/), [GitLab](https://about.gitlab.com/), or [Bitbucket](https://bitbucket.org). You can also create your own custom backend.
|
||||||
|
|
||||||
This tutorial will guide you through the steps for adding Netlify CMS to a site that's built with a common [static site generator](https://www.staticgen.com/), like Jekyll, Hugo, Hexo, or Gatsby. Alternatively, you can [start from a template](https://www.netlifycms.org/docs/start-with-a-template) or dive right into to [configuration options](https://www.netlifycms.org/docs/configuration-options).
|
This tutorial will guide you through the steps for adding Netlify CMS to a site that's built with a common [static site generator](https://www.staticgen.com/), like Jekyll, Hugo, Hexo, or Gatsby. Alternatively, you can [start from a template](https://www.netlifycms.org/docs/start-with-a-template) or dive right into to [configuration options](https://www.netlifycms.org/docs/configuration-options).
|
||||||
@ -126,7 +122,8 @@ public_folder: "/images/uploads" # The src attribute for uploaded media will beg
|
|||||||
|
|
||||||
The configuration above adds a new setting, `public_folder`. While `media_folder` specifies where uploaded files will be saved in the repo, `public_folder` indicates where they can be found in the published site. This path is used in image `src` attributes and is relative to the file where it's called. For this reason, we usually start the path at the site root, using the opening `/`.
|
The configuration above adds a new setting, `public_folder`. While `media_folder` specifies where uploaded files will be saved in the repo, `public_folder` indicates where they can be found in the published site. This path is used in image `src` attributes and is relative to the file where it's called. For this reason, we usually start the path at the site root, using the opening `/`.
|
||||||
|
|
||||||
_If `public_folder` is not set, Netlify CMS will default to the same value as `media_folder`, adding an opening `/` if one is not included._
|
*If `public_folder` is not set, Netlify CMS will default to the same value as `media_folder`, adding an opening `/` if one is not included.*
|
||||||
|
|
||||||
|
|
||||||
### Collections
|
### Collections
|
||||||
|
|
@ -1,13 +1,9 @@
|
|||||||
---
|
---
|
||||||
title: Architecture
|
title: Architecture
|
||||||
weight: 90
|
position: 90
|
||||||
menu:
|
group: contributing
|
||||||
docs:
|
|
||||||
parent: reference
|
|
||||||
---
|
---
|
||||||
|
|
||||||
# Technical Architecture
|
|
||||||
|
|
||||||
Netlify CMS is a React application, using Redux for state management with immutable data structures (immutable.js).
|
Netlify CMS is a React application, using Redux for state management with immutable data structures (immutable.js).
|
||||||
|
|
||||||
The core abstractions for content editing are `collections`, `entries` and `widgets`.
|
The core abstractions for content editing are `collections`, `entries` and `widgets`.
|
@ -1,11 +1,8 @@
|
|||||||
---
|
---
|
||||||
title: Authentication & Backends
|
title: Authentication & Backends
|
||||||
weight: 25
|
weight: 25
|
||||||
menu:
|
group: start
|
||||||
docs:
|
|
||||||
parent: start
|
|
||||||
---
|
---
|
||||||
# Authentication & Backends
|
|
||||||
|
|
||||||
Netlify CMS stores content in your GitHub, GitLab, or Bitbucket repository. In order for this to work, you need to authenticate with your Git host, and in most cases that requires a server. We have a few options for handling this.
|
Netlify CMS stores content in your GitHub, GitLab, or Bitbucket repository. In order for this to work, you need to authenticate with your Git host, and in most cases that requires a server. We have a few options for handling this.
|
||||||
|
|
@ -1,11 +1,9 @@
|
|||||||
---
|
---
|
||||||
title: Beta Features!
|
title: Beta Features!
|
||||||
weight: 200
|
weight: 200
|
||||||
menu:
|
group: reference
|
||||||
docs:
|
|
||||||
parent: reference
|
|
||||||
---
|
---
|
||||||
# Beta Features!
|
|
||||||
We run new functionality in an open beta format from time to time. That means that this functionality is totally available for use, and we _think_ it might be ready for primetime, but it could break or change without notice.
|
We run new functionality in an open beta format from time to time. That means that this functionality is totally available for use, and we _think_ it might be ready for primetime, but it could break or change without notice.
|
||||||
|
|
||||||
**Use these features at your own risk.**
|
**Use these features at your own risk.**
|
@ -1,11 +1,8 @@
|
|||||||
---
|
---
|
||||||
title: Collection Types
|
title: Collection Types
|
||||||
weight: 27
|
weight: 27
|
||||||
menu:
|
group: start
|
||||||
docs:
|
|
||||||
parent: start
|
|
||||||
---
|
---
|
||||||
# Collection Types
|
|
||||||
|
|
||||||
All editable content types are defined in the `collections` field of your `config.yml` file, and display in the left sidebar of the Content page of the editor UI.
|
All editable content types are defined in the `collections` field of your `config.yml` file, and display in the left sidebar of the Content page of the editor UI.
|
||||||
|
|
@ -1,13 +1,9 @@
|
|||||||
---
|
---
|
||||||
title: Configuration Options
|
title: Configuration Options
|
||||||
weight: 23
|
weight: 23
|
||||||
menu:
|
group: reference
|
||||||
docs:
|
|
||||||
parent: reference
|
|
||||||
---
|
---
|
||||||
|
|
||||||
# Configuration Options
|
|
||||||
|
|
||||||
All configuration options for Netlify CMS are specified in a `config.yml` file, in the folder where you access the editor UI (usually in the `/admin` folder).
|
All configuration options for Netlify CMS are specified in a `config.yml` file, in the folder where you access the editor UI (usually in the `/admin` folder).
|
||||||
|
|
||||||
Alternatively, you can specify a custom config file using a link tag:
|
Alternatively, you can specify a custom config file using a link tag:
|
@ -1,13 +1,9 @@
|
|||||||
---
|
---
|
||||||
title: Contributor Guide
|
title: Contributor Guide
|
||||||
weight: 100
|
weight: 100
|
||||||
menu:
|
group: contributing
|
||||||
docs:
|
|
||||||
parent: contributing
|
|
||||||
---
|
---
|
||||||
|
|
||||||
# Welcome, contributors!
|
|
||||||
|
|
||||||
We're hoping that Netlify CMS will do for the [JAMstack](https://www.jamstack.org) what WordPress did for dynamic sites back in the day. We know we can't do that without building a thriving community of contributors and users, and we'd love to have you join us.
|
We're hoping that Netlify CMS will do for the [JAMstack](https://www.jamstack.org) what WordPress did for dynamic sites back in the day. We know we can't do that without building a thriving community of contributors and users, and we'd love to have you join us.
|
||||||
|
|
||||||
While we work on building this page (and you can help!), here are some links with more information about getting involved:
|
While we work on building this page (and you can help!), here are some links with more information about getting involved:
|
@ -1,11 +1,8 @@
|
|||||||
---
|
---
|
||||||
title: Creating Custom Widgets
|
title: Creating Custom Widgets
|
||||||
weight: 35
|
weight: 35
|
||||||
menu:
|
group: guides
|
||||||
docs:
|
|
||||||
parent: guides
|
|
||||||
---
|
---
|
||||||
# Custom Widgets
|
|
||||||
|
|
||||||
The NetlifyCMS exposes a `window.CMS` global object that you can use to register custom widgets, previews, and editor plugins. The same object is also the default export if you import Netify CMS as an npm module. The available widget extension methods are:
|
The NetlifyCMS exposes a `window.CMS` global object that you can use to register custom widgets, previews, and editor plugins. The same object is also the default export if you import Netify CMS as an npm module. The available widget extension methods are:
|
||||||
|
|
@ -1,11 +1,8 @@
|
|||||||
---
|
---
|
||||||
title: Creating Custom Previews
|
title: Creating Custom Previews
|
||||||
weight: 50
|
position: 50
|
||||||
menu:
|
group: guides
|
||||||
docs:
|
|
||||||
parent: guides
|
|
||||||
---
|
---
|
||||||
# Customizing the Preview Pane
|
|
||||||
|
|
||||||
The NetlifyCMS exposes a `window.CMS` global object that you can use to register custom widgets, previews and editor plugins. The available customization methods are:
|
The NetlifyCMS exposes a `window.CMS` global object that you can use to register custom widgets, previews and editor plugins. The available customization methods are:
|
||||||
|
|
@ -1,13 +1,9 @@
|
|||||||
---
|
---
|
||||||
title: Examples
|
title: Examples
|
||||||
weight: 110
|
weight: 110
|
||||||
menu:
|
group: start
|
||||||
docs:
|
|
||||||
parent: start
|
|
||||||
---
|
---
|
||||||
|
|
||||||
# Examples
|
|
||||||
|
|
||||||
Do you have a great, open source example? Submit a pull request to this page!
|
Do you have a great, open source example? Submit a pull request to this page!
|
||||||
|
|
||||||
Example | Tools | Type | Source | More info |
|
Example | Tools | Type | Source | More info |
|
@ -1,13 +1,9 @@
|
|||||||
---
|
---
|
||||||
title: Introduction
|
title: Introduction
|
||||||
weight: 1
|
weight: 1
|
||||||
menu:
|
group: start
|
||||||
docs:
|
|
||||||
parent: start
|
|
||||||
---
|
---
|
||||||
|
|
||||||
# Introduction
|
|
||||||
|
|
||||||
Netlify CMS is an open source content management system for your Git workflow that enables you to provide editors with friendly UI and intuitive workflow. You can use it with any static site generator to create faster, more flexible web projects. Content is stored in your Git repository alongside your code for easier versioning, multi-channel publishing, and the option to handle content updates directly in Git.
|
Netlify CMS is an open source content management system for your Git workflow that enables you to provide editors with friendly UI and intuitive workflow. You can use it with any static site generator to create faster, more flexible web projects. Content is stored in your Git repository alongside your code for easier versioning, multi-channel publishing, and the option to handle content updates directly in Git.
|
||||||
|
|
||||||
At its core, Netlify CMS is an open-source React app that acts as a wrapper for the Git workflow, using the GitHub, GitLab, or Bitbucket API. This provides many advantages, including:
|
At its core, Netlify CMS is an open-source React app that acts as a wrapper for the Git workflow, using the GitHub, GitLab, or Bitbucket API. This provides many advantages, including:
|
@ -1,13 +1,9 @@
|
|||||||
---
|
---
|
||||||
title: Start with a Template
|
title: Start with a Template
|
||||||
weight: 10
|
weight: 10
|
||||||
menu:
|
group: start
|
||||||
docs:
|
|
||||||
parent: start
|
|
||||||
---
|
---
|
||||||
|
|
||||||
# Start with a Template
|
|
||||||
|
|
||||||
Netlify CMS can be [added to an existing site](https://www.netlifycms.org/docs/add-to-your-site), but the quickest way to get started is with a template. Our featured templates below deploy to Netlify, giving you a fully working CMS-enabled site with just a few clicks.
|
Netlify CMS can be [added to an existing site](https://www.netlifycms.org/docs/add-to-your-site), but the quickest way to get started is with a template. Our featured templates below deploy to Netlify, giving you a fully working CMS-enabled site with just a few clicks.
|
||||||
|
|
||||||
<div style="display: flex; justify-content: space-around; text-align: center; margin-bottom: 1.5em;">
|
<div style="display: flex; justify-content: space-around; text-align: center; margin-bottom: 1.5em;">
|
@ -1,13 +1,9 @@
|
|||||||
---
|
---
|
||||||
title: Update the CMS Version
|
title: Update the CMS Version
|
||||||
weight: 60
|
weight: 60
|
||||||
menu:
|
group: start
|
||||||
docs:
|
|
||||||
parent: start
|
|
||||||
---
|
---
|
||||||
|
|
||||||
# Update the CMS Version
|
|
||||||
|
|
||||||
The update procedure for your CMS depends upon the method you used to install Netlify CMS.
|
The update procedure for your CMS depends upon the method you used to install Netlify CMS.
|
||||||
|
|
||||||
## Package Manager
|
## Package Manager
|
@ -1,10 +1,8 @@
|
|||||||
---
|
---
|
||||||
label: "Boolean"
|
label: "Boolean"
|
||||||
target: "boolean"
|
target: boolean
|
||||||
---
|
---
|
||||||
|
|
||||||
### Boolean
|
|
||||||
|
|
||||||
The boolean widget translates a toggle switch input to a true/false value.
|
The boolean widget translates a toggle switch input to a true/false value.
|
||||||
|
|
||||||
- **Name:** `boolean`
|
- **Name:** `boolean`
|
@ -1,10 +1,8 @@
|
|||||||
---
|
---
|
||||||
label: "Date"
|
label: "Date"
|
||||||
target: "date"
|
target: date
|
||||||
---
|
---
|
||||||
|
|
||||||
### Date
|
|
||||||
|
|
||||||
The date widget translates a date picker input to a date string. For saving date and time together, use the datetime widget.
|
The date widget translates a date picker input to a date string. For saving date and time together, use the datetime widget.
|
||||||
|
|
||||||
- **Name:** `date`
|
- **Name:** `date`
|
@ -1,10 +1,8 @@
|
|||||||
---
|
---
|
||||||
label: "DateTime"
|
label: "DateTime"
|
||||||
target: "datetime"
|
target: datetime
|
||||||
---
|
---
|
||||||
|
|
||||||
### DateTime
|
|
||||||
|
|
||||||
The datetime widget translates a datetime picker to a datetime string. For saving the date only, use the date widget.
|
The datetime widget translates a datetime picker to a datetime string. For saving the date only, use the date widget.
|
||||||
|
|
||||||
- **Name:** `datetime`
|
- **Name:** `datetime`
|
@ -1,10 +1,8 @@
|
|||||||
---
|
---
|
||||||
label: "File"
|
label: "File"
|
||||||
target: "file"
|
target: file
|
||||||
---
|
---
|
||||||
|
|
||||||
### File
|
|
||||||
|
|
||||||
The file widget allows editors to upload a file or select an existing one from the media library. The path to the file will be saved to the field as a string.
|
The file widget allows editors to upload a file or select an existing one from the media library. The path to the file will be saved to the field as a string.
|
||||||
|
|
||||||
- **Name:** `file`
|
- **Name:** `file`
|
@ -1,10 +1,8 @@
|
|||||||
---
|
---
|
||||||
label: "Hidden"
|
label: "Hidden"
|
||||||
target: "hidden"
|
target: hidden
|
||||||
---
|
---
|
||||||
|
|
||||||
### Hidden
|
|
||||||
|
|
||||||
Hidden widgets do not display in the UI. In folder collections that allow users to create new items, you will often want to set a default for hidden fields, so they will be set without requiring an input.
|
Hidden widgets do not display in the UI. In folder collections that allow users to create new items, you will often want to set a default for hidden fields, so they will be set without requiring an input.
|
||||||
|
|
||||||
- **Name:** `hidden`
|
- **Name:** `hidden`
|
@ -1,10 +1,8 @@
|
|||||||
---
|
---
|
||||||
label: "Image"
|
label: "Image"
|
||||||
target: "image"
|
target: image
|
||||||
---
|
---
|
||||||
|
|
||||||
### Image
|
|
||||||
|
|
||||||
The image widget allows editors to upload an image or select an existing one from the media library. The path to the image file will be saved to the field as a string.
|
The image widget allows editors to upload an image or select an existing one from the media library. The path to the image file will be saved to the field as a string.
|
||||||
|
|
||||||
- **Name:** `image`
|
- **Name:** `image`
|
@ -1,13 +1,9 @@
|
|||||||
---
|
---
|
||||||
title: Widgets
|
title: Widgets
|
||||||
weight: 30
|
weight: 30
|
||||||
menu:
|
group: reference
|
||||||
docs:
|
|
||||||
parent: reference
|
|
||||||
---
|
---
|
||||||
|
|
||||||
# Widgets
|
|
||||||
|
|
||||||
Widgets define the data type and interface for entry fields. Netlify CMS comes with several built-in widgets. Click the widget names in the sidebar to jump to specific widget details. We’re always adding new widgets, and you can also [create your own](https://www.netlifycms.org/docs/custom-widgets)!
|
Widgets define the data type and interface for entry fields. Netlify CMS comes with several built-in widgets. Click the widget names in the sidebar to jump to specific widget details. We’re always adding new widgets, and you can also [create your own](https://www.netlifycms.org/docs/custom-widgets)!
|
||||||
|
|
||||||
Widgets are specified as collection fields in the Netlify CMS `config.yml` file. Note that [YAML syntax](https://en.wikipedia.org/wiki/YAML#Basic_components) allows lists and objects to be written in block or inline style, and the code samples below include a mix of both.
|
Widgets are specified as collection fields in the Netlify CMS `config.yml` file. Note that [YAML syntax](https://en.wikipedia.org/wiki/YAML#Basic_components) allows lists and objects to be written in block or inline style, and the code samples below include a mix of both.
|
@ -1,10 +1,8 @@
|
|||||||
---
|
---
|
||||||
label: "List"
|
label: "List"
|
||||||
target: "list"
|
target: list
|
||||||
---
|
---
|
||||||
|
|
||||||
### List
|
|
||||||
|
|
||||||
The list widget allows you to create a repeatable item in the UI which saves as a list of widget values. map a user-provided string with a comma delimiter into a list. You can choose any widget as a child of a list widget—even other lists.
|
The list widget allows you to create a repeatable item in the UI which saves as a list of widget values. map a user-provided string with a comma delimiter into a list. You can choose any widget as a child of a list widget—even other lists.
|
||||||
|
|
||||||
- **Name:** `list`
|
- **Name:** `list`
|
@ -1,10 +1,8 @@
|
|||||||
---
|
---
|
||||||
label: "Markdown"
|
label: "Markdown"
|
||||||
target: "markdown"
|
target: markdown
|
||||||
---
|
---
|
||||||
|
|
||||||
### Markdown
|
|
||||||
|
|
||||||
The markdown widget provides a full fledged text editor - which is based on [slate](https://github.com/ianstormtaylor/slate) - that allows users to format text with features such as headings and blockquotes. Users are also allowed to write in markdown by simply flipping a switch.
|
The markdown widget provides a full fledged text editor - which is based on [slate](https://github.com/ianstormtaylor/slate) - that allows users to format text with features such as headings and blockquotes. Users are also allowed to write in markdown by simply flipping a switch.
|
||||||
|
|
||||||
*Please note:* in case you want to use your markdown editor to fill a markdown's file content after the frontmatter, you'll have name the field as `body` so then the CMS can recognize it and save the file accordingly.
|
*Please note:* in case you want to use your markdown editor to fill a markdown's file content after the frontmatter, you'll have name the field as `body` so then the CMS can recognize it and save the file accordingly.
|
@ -1,11 +1,8 @@
|
|||||||
---
|
---
|
||||||
label: "Number"
|
label: "Number"
|
||||||
target: "number"
|
target: number
|
||||||
---
|
---
|
||||||
|
|
||||||
### Number
|
|
||||||
|
|
||||||
|
|
||||||
The number widget uses an HTML number input, saving the value as a string, integer, or floating point number.
|
The number widget uses an HTML number input, saving the value as a string, integer, or floating point number.
|
||||||
|
|
||||||
- **Name:** `number`
|
- **Name:** `number`
|
@ -1,10 +1,8 @@
|
|||||||
---
|
---
|
||||||
label: "Object"
|
label: "Object"
|
||||||
target: "object"
|
target: object
|
||||||
---
|
---
|
||||||
|
|
||||||
### Object
|
|
||||||
|
|
||||||
The object widget allows you to group multiple widgets together, nested under a single field. You can choose any widget as a child of an object widget—even other objects.
|
The object widget allows you to group multiple widgets together, nested under a single field. You can choose any widget as a child of an object widget—even other objects.
|
||||||
|
|
||||||
- **Name:** `object`
|
- **Name:** `object`
|
@ -1,10 +1,8 @@
|
|||||||
---
|
---
|
||||||
label: "Relation"
|
label: "Relation"
|
||||||
target: "relation"
|
target: relation
|
||||||
---
|
---
|
||||||
|
|
||||||
### Relation
|
|
||||||
|
|
||||||
The relation widget allows you to reference items from another collection. It provides a search input with a list of entries from the collection you're referencing, and the list automatically updates with matched entries based on what you've typed.
|
The relation widget allows you to reference items from another collection. It provides a search input with a list of entries from the collection you're referencing, and the list automatically updates with matched entries based on what you've typed.
|
||||||
|
|
||||||
- **Name:** `relation`
|
- **Name:** `relation`
|
@ -1,10 +1,8 @@
|
|||||||
---
|
---
|
||||||
label: "Select"
|
label: "Select"
|
||||||
target: "select"
|
target: select
|
||||||
---
|
---
|
||||||
|
|
||||||
### Select
|
|
||||||
|
|
||||||
The select widget allows you to pick a single string value from a dropdown menu.
|
The select widget allows you to pick a single string value from a dropdown menu.
|
||||||
|
|
||||||
- **Name:** `select`
|
- **Name:** `select`
|
@ -1,10 +1,8 @@
|
|||||||
---
|
---
|
||||||
label: "String"
|
label: "String"
|
||||||
target: "string"
|
target: string
|
||||||
---
|
---
|
||||||
|
|
||||||
### String
|
|
||||||
|
|
||||||
The string widget translates a basic text input to a string value. For larger textarea inputs, use the text widget.
|
The string widget translates a basic text input to a string value. For larger textarea inputs, use the text widget.
|
||||||
|
|
||||||
- **Name:** `string`
|
- **Name:** `string`
|
@ -1,10 +1,8 @@
|
|||||||
---
|
---
|
||||||
label: "Text"
|
label: "Text"
|
||||||
target: "text"
|
target: text
|
||||||
---
|
---
|
||||||
|
|
||||||
### Text
|
|
||||||
|
|
||||||
The text widget takes a multiline text field and saves it as a string. For shorter text inputs, use the string widget.
|
The text widget takes a multiline text field and saves it as a string. For shorter text inputs, use the string widget.
|
||||||
|
|
||||||
- **Name:** `text`
|
- **Name:** `text`
|
@ -1,7 +1,5 @@
|
|||||||
---
|
---
|
||||||
title: Community
|
title: Community
|
||||||
layout: community
|
|
||||||
url: /community
|
|
||||||
|
|
||||||
headline: Be a part of building the CMS of the future.
|
headline: Be a part of building the CMS of the future.
|
||||||
subhead: We’re serious about being community driven, so everyone is welcome to join the [community chat](https://gitter.im/netlify/NetlifyCMS), and to be a part of our bi-weekly planning sessions (details below).
|
subhead: We’re serious about being community driven, so everyone is welcome to join the [community chat](https://gitter.im/netlify/NetlifyCMS), and to be a part of our bi-weekly planning sessions (details below).
|
@ -1,4 +1,3 @@
|
|||||||
---
|
|
||||||
styleoverrides: '/docs.css'
|
styleoverrides: '/docs.css'
|
||||||
headline: Netlify builds, deploys, and hosts your front end.
|
headline: Netlify builds, deploys, and hosts your front end.
|
||||||
bottomcta:
|
bottomcta:
|
||||||
@ -10,4 +9,3 @@ bottomcta:
|
|||||||
- type: secondary
|
- type: secondary
|
||||||
btntext: Read our Tutorials
|
btntext: Read our Tutorials
|
||||||
linksto: /tags/tutorial/
|
linksto: /tags/tutorial/
|
||||||
---
|
|
@ -1,8 +1,6 @@
|
|||||||
---
|
|
||||||
footer:
|
footer:
|
||||||
buttons:
|
buttons:
|
||||||
- name: "Twitter"
|
- name: "Twitter"
|
||||||
url: "https://twitter.com/netlifycms"
|
url: "https://twitter.com/netlifycms"
|
||||||
- name: "GitHub"
|
- name: "GitHub"
|
||||||
url: "https://github.com/netlify/netlify-cms"
|
url: "https://github.com/netlify/netlify-cms"
|
||||||
---
|
|
@ -1,4 +1,3 @@
|
|||||||
---
|
|
||||||
hero:
|
hero:
|
||||||
headline: "Open source content management for your Git workflow"
|
headline: "Open source content management for your Git workflow"
|
||||||
subhead: "Use Netlify CMS with any static site generator for a faster and more flexible web project"
|
subhead: "Use Netlify CMS with any static site generator for a faster and more flexible web project"
|
||||||
@ -21,13 +20,13 @@ editors:
|
|||||||
features:
|
features:
|
||||||
- feature: "Editor-friendly user interface"
|
- feature: "Editor-friendly user interface"
|
||||||
description: "The web-based app includes rich-text editing, real-time preview, and drag-and-drop media uploads."
|
description: "The web-based app includes rich-text editing, real-time preview, and drag-and-drop media uploads."
|
||||||
imgpath: "/img/feature-editor.svg"
|
imgpath: "feature-editor.svg"
|
||||||
- feature: "Intuitive workflow for content teams"
|
- feature: "Intuitive workflow for content teams"
|
||||||
description: "Writers and editors can easily manage content from draft to review to publish across any number of custom content types."
|
description: "Writers and editors can easily manage content from draft to review to publish across any number of custom content types."
|
||||||
imgpath: "/img/feature-workflow.svg"
|
imgpath: "feature-workflow.svg"
|
||||||
- feature: "Instant access without GitHub account"
|
- feature: "Instant access without GitHub account"
|
||||||
description: "With [Git Gateway](/docs/authentication-backends/#git-gateway-with-netlify-identity), you can add CMS access for any team member — even if they don’t have a GitHub account. "
|
description: "With [Git Gateway](/docs/authentication-backends/#git-gateway-with-netlify-identity), you can add CMS access for any team member — even if they don’t have a GitHub account. "
|
||||||
imgpath: "/img/feature-access.svg"
|
imgpath: "feature-access.svg"
|
||||||
|
|
||||||
community:
|
community:
|
||||||
hook: "Supported by a growing community"
|
hook: "Supported by a growing community"
|
||||||
@ -40,4 +39,3 @@ community:
|
|||||||
description: "Netlify CMS is built by a community of more than 100 contributors — and you can help. Join our [bi-weekly planning sessions](/community) or read the [contributing guide](/docs/contributor-guide) to join in."
|
description: "Netlify CMS is built by a community of more than 100 contributors — and you can help. Join our [bi-weekly planning sessions](/community) or read the [contributing guide](/docs/contributor-guide) to join in."
|
||||||
contributors: "Made possible by awesome contributors"
|
contributors: "Made possible by awesome contributors"
|
||||||
|
|
||||||
---
|
|
22
website/data/notifications.yml
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
notifications:
|
||||||
|
- loud: true
|
||||||
|
message: >-
|
||||||
|
Register to join us online for our next community dev meeting, every other
|
||||||
|
Wednesday at 9am-10am PT!
|
||||||
|
published: false
|
||||||
|
title: Netlify CMS Development Planning Sessions Promo
|
||||||
|
url: >-
|
||||||
|
https://www.eventbrite.com/e/netlify-cms-planning-session-bi-weekly-tickets-35794058994
|
||||||
|
- loud: true
|
||||||
|
message: >-
|
||||||
|
We have a community on Gitter - join now to ask questions and discuss the
|
||||||
|
project with other devs!
|
||||||
|
published: false
|
||||||
|
title: Gitter shoutout
|
||||||
|
url: 'https://gitter.im/netlify/netlifycms'
|
||||||
|
- loud: true
|
||||||
|
message: >-
|
||||||
|
Netlify CMS now supports GitLab!
|
||||||
|
published: true
|
||||||
|
title: GitLab announcement
|
||||||
|
url: '/blog/2018/06/netlify-cms-now-supports-gitlab-as-a-backend/'
|
@ -45,59 +45,59 @@ updates:
|
|||||||
- date: '2018-03-29'
|
- date: '2018-03-29'
|
||||||
description: 'More control over filenames, lots of bugfixes, and new beta features!'
|
description: 'More control over filenames, lots of bugfixes, and new beta features!'
|
||||||
version: 1.4.0
|
version: 1.4.0
|
||||||
- date: 2018-03-06T00:00:00.000Z
|
- date: '2018-03-06'
|
||||||
description: Fixes styling issues
|
description: Fixes styling issues
|
||||||
version: 1.3.5
|
version: 1.3.5
|
||||||
- date: 2018-03-06T00:00:00.000Z
|
- date: '2018-03-06'
|
||||||
description: Fixes editorial workflow entry failure.
|
description: Fixes editorial workflow entry failure.
|
||||||
version: 1.3.4
|
version: 1.3.4
|
||||||
- date: 2018-03-06T00:00:00.000Z
|
- date: '2018-03-06'
|
||||||
description: Fixes load failure
|
description: Fixes load failure
|
||||||
version: 1.3.3
|
version: 1.3.3
|
||||||
- date: 2018-03-06T00:00:00.000Z
|
- date: '2018-03-06'
|
||||||
description: >-
|
description: >-
|
||||||
Fixes date widget default format, collection load failure when entry
|
Fixes date widget default format, collection load failure when entry
|
||||||
fails.
|
fails.
|
||||||
version: 1.3.2
|
version: 1.3.2
|
||||||
- date: 2018-03-03T00:00:00.000Z
|
- date: '2018-03-03'
|
||||||
description: Fixes editorial workflow failure for unknown collections.
|
description: Fixes editorial workflow failure for unknown collections.
|
||||||
version: 1.3.1
|
version: 1.3.1
|
||||||
- date: 2018-02-27T00:00:00.000Z
|
- date: '2018-02-27'
|
||||||
description: >-
|
description: >-
|
||||||
Multi-part extensions, e.g. "en.md", a11y improvements in the editor, and
|
Multi-part extensions, e.g. "en.md", a11y improvements in the editor, and
|
||||||
bugfixes.
|
bugfixes.
|
||||||
version: 1.3.0
|
version: 1.3.0
|
||||||
- date: 2018-02-21T00:00:00.000Z
|
- date: '2018-02-21'
|
||||||
description: Fixes ES5 transpiling.
|
description: Fixes ES5 transpiling.
|
||||||
version: 1.2.2
|
version: 1.2.2
|
||||||
- date: 2018-02-21T00:00:00.000Z
|
- date: '2018-02-21'
|
||||||
description: >-
|
description: >-
|
||||||
Allows label_singular config for collections and lists and distinct
|
Allows label_singular config for collections and lists and distinct
|
||||||
frontmatter delimiters.
|
frontmatter delimiters.
|
||||||
version: 1.2.1
|
version: 1.2.1
|
||||||
- date: 2018-02-13T00:00:00.000Z
|
- date: '2018-02-13'
|
||||||
description: >-
|
description: >-
|
||||||
Adds support for multiple frontmatter formats and custom delimiters, UI
|
Adds support for multiple frontmatter formats and custom delimiters, UI
|
||||||
improvements.
|
improvements.
|
||||||
version: '1.2'
|
version: '1.2'
|
||||||
- date: 2018-01-25T00:00:00.000Z
|
- date: '2018-01-25'
|
||||||
description: You can now register external backends and we improved metadata handling.
|
description: You can now register external backends and we improved metadata handling.
|
||||||
version: '1.1'
|
version: '1.1'
|
||||||
- date: 2018-01-23T00:00:00.000Z
|
- date: '2018-01-23'
|
||||||
description: >-
|
description: >-
|
||||||
Fixes various UI bugs and adds expand / collapse functionality to the
|
Fixes various UI bugs and adds expand / collapse functionality to the
|
||||||
object widget.
|
object widget.
|
||||||
version: 1.0.4
|
version: 1.0.4
|
||||||
- date: 2018-12-19T00:00:00.000Z
|
- date: '2018-12-19'
|
||||||
description: Small bug fix release.
|
description: Small bug fix release.
|
||||||
version: 1.0.3
|
version: 1.0.3
|
||||||
- date: 2018-12-07T00:00:00.000Z
|
- date: '2018-12-07'
|
||||||
description: Small bug fix release.
|
description: Small bug fix release.
|
||||||
version: 1.0.2
|
version: 1.0.2
|
||||||
- date: 2018-12-07T00:00:00.000Z
|
- date: '2018-12-07'
|
||||||
description: Small bug fix release.
|
description: Small bug fix release.
|
||||||
version: 1.0.1
|
version: 1.0.1
|
||||||
- date: 2018-12-07T00:00:00.000Z
|
- date: '2018-12-07'
|
||||||
description: >-
|
description: >-
|
||||||
The first major release of Netlify CMS with an all-new UI, revamped
|
The first major release of Netlify CMS with an all-new UI, revamped
|
||||||
documentation and much more.
|
documentation and much more.
|
10
website/gatsby-browser.js
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
import SmoothScroll from 'smooth-scroll';
|
||||||
|
|
||||||
|
// Make scroll behavior of internal links smooth
|
||||||
|
exports.onClientEntry = () => {
|
||||||
|
new SmoothScroll('a[href*="#"]', {
|
||||||
|
offset() {
|
||||||
|
return document.querySelector('#header').offsetHeight;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
96
website/gatsby-config.js
Normal file
@ -0,0 +1,96 @@
|
|||||||
|
const pkg = require('./package.json');
|
||||||
|
|
||||||
|
const neatgrid = require('postcss-neat');
|
||||||
|
const nestedcss = require('postcss-nested');
|
||||||
|
const colorfunctions = require('postcss-colour-functions');
|
||||||
|
const hdBackgrounds = require('postcss-at2x');
|
||||||
|
const cssextend = require('postcss-simple-extend');
|
||||||
|
const cssvars = require('postcss-simple-vars-async');
|
||||||
|
|
||||||
|
const styleVariables = require('./src/theme');
|
||||||
|
|
||||||
|
const postCssPlugins = [
|
||||||
|
neatgrid(),
|
||||||
|
nestedcss(),
|
||||||
|
colorfunctions(),
|
||||||
|
hdBackgrounds(),
|
||||||
|
cssextend(),
|
||||||
|
cssvars({ variables: styleVariables })
|
||||||
|
];
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
siteMetadata: {
|
||||||
|
title: 'Netlify CMS | Open-Source Content Management System',
|
||||||
|
description: 'Open source content management for your Git workflow',
|
||||||
|
siteUrl: pkg.homepage,
|
||||||
|
menu: {
|
||||||
|
docs: [
|
||||||
|
{
|
||||||
|
name: 'start',
|
||||||
|
title: 'Quick Start'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'guides',
|
||||||
|
title: 'Guides'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'reference',
|
||||||
|
title: 'Reference'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'contributing',
|
||||||
|
title: 'Contributing'
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
plugins: [
|
||||||
|
{
|
||||||
|
resolve: 'gatsby-source-filesystem',
|
||||||
|
options: {
|
||||||
|
path: `${__dirname}/content`,
|
||||||
|
name: 'content'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
'gatsby-transformer-yaml',
|
||||||
|
'gatsby-transformer-json',
|
||||||
|
{
|
||||||
|
resolve: 'gatsby-source-filesystem',
|
||||||
|
options: {
|
||||||
|
path: `${__dirname}/data`,
|
||||||
|
name: 'data'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
resolve: 'gatsby-transformer-remark',
|
||||||
|
options: {
|
||||||
|
// prettier-ignore
|
||||||
|
plugins: [
|
||||||
|
'gatsby-remark-autolink-headers',
|
||||||
|
'gatsby-remark-prismjs'
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
resolve: 'gatsby-plugin-postcss-sass',
|
||||||
|
options: {
|
||||||
|
postCssPlugins
|
||||||
|
}
|
||||||
|
},
|
||||||
|
'gatsby-plugin-react-helmet',
|
||||||
|
'gatsby-plugin-react-next',
|
||||||
|
'gatsby-plugin-catch-links',
|
||||||
|
{
|
||||||
|
resolve: `gatsby-plugin-manifest`,
|
||||||
|
options: {
|
||||||
|
name: 'NetlifyCMS',
|
||||||
|
short_name: 'NetlifyCMS',
|
||||||
|
start_url: '/',
|
||||||
|
background_color: '#ffffff',
|
||||||
|
theme_color: '#ffffff',
|
||||||
|
display: 'standalone',
|
||||||
|
icon: 'static/img/favicon/icon-512x512.png'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
};
|
91
website/gatsby-node.js
Normal file
@ -0,0 +1,91 @@
|
|||||||
|
const path = require('path');
|
||||||
|
const { createFilePath } = require('gatsby-source-filesystem');
|
||||||
|
|
||||||
|
exports.createPages = async ({ graphql, boundActionCreators }) => {
|
||||||
|
const { createPage } = boundActionCreators;
|
||||||
|
|
||||||
|
const docPage = path.resolve('./src/templates/doc-page.js');
|
||||||
|
const blogPost = path.resolve('./src/templates/blog-post.js');
|
||||||
|
|
||||||
|
// get all markdown with a frontmatter path field and title
|
||||||
|
const allMarkdown = await graphql(`
|
||||||
|
{
|
||||||
|
allMarkdownRemark(filter: { frontmatter: { title: { ne: null } } }) {
|
||||||
|
edges {
|
||||||
|
node {
|
||||||
|
fields {
|
||||||
|
slug
|
||||||
|
}
|
||||||
|
frontmatter {
|
||||||
|
title
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`);
|
||||||
|
|
||||||
|
if (allMarkdown.errors) {
|
||||||
|
console.error(allMarkdown.errors);
|
||||||
|
throw Error(allMarkdown.errors);
|
||||||
|
}
|
||||||
|
|
||||||
|
allMarkdown.data.allMarkdownRemark.edges.forEach(({ node }) => {
|
||||||
|
const { slug } = node.fields;
|
||||||
|
|
||||||
|
let template = docPage;
|
||||||
|
|
||||||
|
if (slug.includes('blog/')) {
|
||||||
|
template = blogPost;
|
||||||
|
}
|
||||||
|
|
||||||
|
createPage({
|
||||||
|
path: slug,
|
||||||
|
component: template,
|
||||||
|
context: {
|
||||||
|
slug
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
const pad = n => (n >= 10 ? n : `0${n}`);
|
||||||
|
|
||||||
|
exports.onCreateNode = ({ node, boundActionCreators, getNode }) => {
|
||||||
|
const { createNodeField } = boundActionCreators;
|
||||||
|
|
||||||
|
if (node.internal.type === 'MarkdownRemark') {
|
||||||
|
const value = createFilePath({ node, getNode });
|
||||||
|
const { relativePath } = getNode(node.parent);
|
||||||
|
|
||||||
|
let slug = value;
|
||||||
|
|
||||||
|
if (relativePath.includes('blog/')) {
|
||||||
|
const date = new Date(node.frontmatter.date);
|
||||||
|
const year = date.getFullYear();
|
||||||
|
const month = date.getMonth() + 1;
|
||||||
|
const filename = path.basename(relativePath, '.md');
|
||||||
|
slug = `/blog/${year}/${pad(month)}/${filename}`;
|
||||||
|
|
||||||
|
createNodeField({
|
||||||
|
node,
|
||||||
|
name: 'date',
|
||||||
|
value: date.toJSON()
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// used for doc posts
|
||||||
|
createNodeField({
|
||||||
|
node,
|
||||||
|
name: 'slug',
|
||||||
|
value: slug
|
||||||
|
});
|
||||||
|
|
||||||
|
// used to create GitHub edit link
|
||||||
|
createNodeField({
|
||||||
|
node,
|
||||||
|
name: 'path',
|
||||||
|
value: relativePath
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
@ -1,128 +0,0 @@
|
|||||||
import gulp from "gulp";
|
|
||||||
import cp from "child_process";
|
|
||||||
import hugoBin from "hugo-bin";
|
|
||||||
import gutil from "gulp-util";
|
|
||||||
import postcss from "gulp-postcss";
|
|
||||||
import transform from "gulp-transform";
|
|
||||||
import yaml from "yamljs";
|
|
||||||
import rename from "gulp-rename";
|
|
||||||
import cssImport from "postcss-import";
|
|
||||||
import neatgrid from "postcss-neat";
|
|
||||||
import nestedcss from "postcss-nested";
|
|
||||||
import colorfunctions from "postcss-colour-functions";
|
|
||||||
import hdBackgrounds from "postcss-at2x";
|
|
||||||
import cssvars from "postcss-simple-vars-async";
|
|
||||||
import cssextend from "postcss-simple-extend";
|
|
||||||
import styleVariables from "./config/variables";
|
|
||||||
import BrowserSync from "browser-sync";
|
|
||||||
import webpack from "webpack";
|
|
||||||
import webpackConfig from "./webpack.conf";
|
|
||||||
import url from "url";
|
|
||||||
|
|
||||||
// Always exit non-zero on unhandled promise rejection
|
|
||||||
process.on('unhandledRejection', err => { throw err });
|
|
||||||
|
|
||||||
const browserSync = BrowserSync.create();
|
|
||||||
const defaultArgs = ["-d", "../dist", "-s", "site", "-v"];
|
|
||||||
|
|
||||||
function buildSite(cb, options) {
|
|
||||||
const args = options ? defaultArgs.concat(options) : defaultArgs;
|
|
||||||
return cp.spawn(hugoBin, args, { stdio: "inherit" }).on("close", code => {
|
|
||||||
if (code === 0) {
|
|
||||||
browserSync.reload();
|
|
||||||
cb();
|
|
||||||
} else {
|
|
||||||
browserSync.notify("Hugo build failed :(");
|
|
||||||
cb("Hugo build failed");
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
gulp.task("hugo", ["copy"], cb => buildSite(cb));
|
|
||||||
gulp.task("hugo-preview", ["copy"], cb =>
|
|
||||||
buildSite(cb, ["--buildDrafts", "--buildFuture"])
|
|
||||||
);
|
|
||||||
|
|
||||||
gulp.task("build", ["css", "js", "images", "hugo"]);
|
|
||||||
gulp.task("build-preview", ["css", "js", "images", "hugo-preview"]);
|
|
||||||
|
|
||||||
gulp.task("css", () =>
|
|
||||||
gulp
|
|
||||||
.src("./src/css/**/*.css")
|
|
||||||
.pipe(
|
|
||||||
postcss([
|
|
||||||
cssImport({ from: "./src/css/main.css" }),
|
|
||||||
neatgrid(),
|
|
||||||
nestedcss(),
|
|
||||||
colorfunctions(),
|
|
||||||
hdBackgrounds(),
|
|
||||||
cssextend(),
|
|
||||||
cssvars({ variables: styleVariables })
|
|
||||||
])
|
|
||||||
)
|
|
||||||
.pipe(gulp.dest("./dist/css"))
|
|
||||||
.pipe(browserSync.stream())
|
|
||||||
);
|
|
||||||
|
|
||||||
gulp.task("js", cb => {
|
|
||||||
const myConfig = Object.assign({}, webpackConfig);
|
|
||||||
|
|
||||||
webpack(myConfig, (err, stats) => {
|
|
||||||
if (err) throw new gutil.PluginError("webpack", err);
|
|
||||||
gutil.log(
|
|
||||||
"[webpack]",
|
|
||||||
stats.toString({
|
|
||||||
colors: true,
|
|
||||||
progress: true
|
|
||||||
})
|
|
||||||
);
|
|
||||||
browserSync.reload();
|
|
||||||
cb();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
gulp.task("images", () =>
|
|
||||||
gulp
|
|
||||||
.src("./src/img/**/*")
|
|
||||||
.pipe(gulp.dest("./dist/img"))
|
|
||||||
.pipe(browserSync.stream())
|
|
||||||
);
|
|
||||||
|
|
||||||
gulp.task("copy", () =>
|
|
||||||
gulp
|
|
||||||
.src("../.all-contributorsrc")
|
|
||||||
.pipe(
|
|
||||||
transform(
|
|
||||||
"utf8",
|
|
||||||
content =>
|
|
||||||
new Promise((resolve, reject) => {
|
|
||||||
const contributors = JSON.parse(content).contributors.map(c => {
|
|
||||||
const avatar = url.parse(c['avatar_url'], true);
|
|
||||||
avatar.search = undefined; // Override so that we can use `avatar.query`.
|
|
||||||
if (avatar.hostname.endsWith('githubusercontent.com')) {
|
|
||||||
// Use 32px avatars, instead of full-size.
|
|
||||||
avatar.query['s'] = '32';
|
|
||||||
}
|
|
||||||
const avatar_url = url.format(avatar);
|
|
||||||
return Object.assign({}, c, { avatar_url });
|
|
||||||
});
|
|
||||||
resolve(yaml.dump({ contributors }));
|
|
||||||
})
|
|
||||||
)
|
|
||||||
)
|
|
||||||
.pipe(rename("contributors.yml"))
|
|
||||||
.pipe(gulp.dest("./site/data"))
|
|
||||||
);
|
|
||||||
|
|
||||||
gulp.task("server", ["css", "js", "images", "hugo"], () => {
|
|
||||||
browserSync.init({
|
|
||||||
server: {
|
|
||||||
baseDir: "./dist"
|
|
||||||
},
|
|
||||||
notify: false
|
|
||||||
});
|
|
||||||
gulp.watch("./src/js/**/*.js", ["js"]);
|
|
||||||
gulp.watch("./src/css/**/*.css", ["css"]);
|
|
||||||
gulp.watch("./src/img/**/*", ["images"]);
|
|
||||||
gulp.watch("./site/**/*", ["hugo"]);
|
|
||||||
});
|
|
@ -1,55 +1,46 @@
|
|||||||
{
|
{
|
||||||
"name": "victor-hugo",
|
"name": "netlify-cms-site",
|
||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"description": "Victor Hugo is a Hugo boilerplate for creating truly epic websites!",
|
"description": "Netlify CMS documentation website built with Gatsby",
|
||||||
"main": "index.js",
|
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"hugo": "gulp hugo",
|
"start": "gatsby develop",
|
||||||
"webpack": "gulp webpack",
|
"build": "gatsby build && mv public dist",
|
||||||
"build": "gulp build",
|
"copy:contribs": "cp ../.all-contributorsrc data/contributors.json",
|
||||||
"build-preview": "gulp build-preview",
|
"prepare": "npm run copy:contribs",
|
||||||
"start": "gulp server",
|
"reset": "rm -rf .cache",
|
||||||
"lint": "eslint src"
|
"lint": "eslint src"
|
||||||
},
|
},
|
||||||
"author": "",
|
"author": "",
|
||||||
|
"homepage": "https://www.netlifycms.org/",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"autoprefixer": "^6.3.7",
|
"classnames": "^2.2.5",
|
||||||
"babel-eslint": "^6.1.2",
|
|
||||||
"babel-loader": "^6.2.4",
|
|
||||||
"babel-plugin-syntax-object-rest-spread": "^6.13.0",
|
|
||||||
"babel-plugin-transform-class-properties": "^6.10.2",
|
|
||||||
"babel-plugin-transform-object-assign": "^6.8.0",
|
|
||||||
"babel-plugin-transform-object-rest-spread": "^6.8.0",
|
|
||||||
"babel-preset-es2015": "^6.9.0",
|
|
||||||
"babel-register": "^6.11.6",
|
|
||||||
"browser-sync": "^2.13.0",
|
|
||||||
"css-loader": "^0.23.1",
|
|
||||||
"eslint": "^3.1.1",
|
"eslint": "^3.1.1",
|
||||||
"eslint-plugin-import": "^1.11.1",
|
"eslint-plugin-import": "^1.11.1",
|
||||||
"exports-loader": "^0.6.3",
|
"gatsby": "^1.9.270",
|
||||||
"file-loader": "^0.9.0",
|
"gatsby-plugin-catch-links": "^1.0.22",
|
||||||
"gulp": "^3.9.1",
|
"gatsby-plugin-manifest": "^1.0.21",
|
||||||
"gulp-babel": "^6.1.2",
|
"gatsby-plugin-postcss-sass": "^1.0.20",
|
||||||
"gulp-postcss": "^6.1.1",
|
"gatsby-plugin-react-helmet": "^2.0.11",
|
||||||
"gulp-rename": "^1.2.2",
|
"gatsby-plugin-react-next": "^1.0.11",
|
||||||
"gulp-transform": "^3.0.5",
|
"gatsby-remark-autolink-headers": "^1.4.18",
|
||||||
"gulp-util": "^3.0.7",
|
"gatsby-remark-prismjs": "^2.0.2",
|
||||||
"hugo-bin": "^0.23.0",
|
"gatsby-source-filesystem": "^1.5.35",
|
||||||
"imports-loader": "^0.6.5",
|
"gatsby-transformer-json": "^1.0.17",
|
||||||
|
"gatsby-transformer-remark": "^1.7.42",
|
||||||
|
"gatsby-transformer-yaml": "^1.5.16",
|
||||||
"postcss-at2x": "^2.0.0",
|
"postcss-at2x": "^2.0.0",
|
||||||
"postcss-colour-functions": "^1.5.1",
|
"postcss-colour-functions": "^1.5.1",
|
||||||
"postcss-cssnext": "^2.7.0",
|
"postcss-cssnext": "^2.7.0",
|
||||||
"postcss-import": "^8.1.2",
|
|
||||||
"postcss-loader": "^0.9.1",
|
|
||||||
"postcss-neat": "^2.5.2",
|
"postcss-neat": "^2.5.2",
|
||||||
"postcss-nested": "^1.0.0",
|
"postcss-nested": "^1.0.0",
|
||||||
"postcss-simple-extend": "^1.0.0",
|
"postcss-simple-extend": "^1.0.0",
|
||||||
"postcss-simple-vars-async": "^1.2.1",
|
"postcss-simple-vars-async": "^1.2.1",
|
||||||
"url-loader": "^0.5.7",
|
"prismjs": "^1.14.0",
|
||||||
"webpack": "^1.13.1",
|
"react-helmet": "^5.2.0",
|
||||||
"whatwg-fetch": "^1.0.0",
|
"react-markdown": "^3.3.2",
|
||||||
"yamljs": "^0.2.8"
|
"react-sidecar": "^0.1.1",
|
||||||
|
"smooth-scroll": "^14.2.0"
|
||||||
},
|
},
|
||||||
"devDependencies": {}
|
"devDependencies": {}
|
||||||
}
|
}
|
||||||
|
@ -1,22 +0,0 @@
|
|||||||
baseurl: "https://www.netlifycms.org/"
|
|
||||||
languageCode: "en-us"
|
|
||||||
title: "Netlify CMS | Open-Source Content Management System"
|
|
||||||
disable404: true
|
|
||||||
pluralizeListTitles: false
|
|
||||||
metaDataFormat: "yaml"
|
|
||||||
permalinks:
|
|
||||||
blog: /blog/:year/:month/:title/
|
|
||||||
menu:
|
|
||||||
docs:
|
|
||||||
- name: start
|
|
||||||
title: Quick Start
|
|
||||||
weight: 100
|
|
||||||
- name: guides
|
|
||||||
title: Guides
|
|
||||||
weight: 200
|
|
||||||
- name: reference
|
|
||||||
title: Reference
|
|
||||||
weight: 300
|
|
||||||
- name: contributing
|
|
||||||
title: Contributing
|
|
||||||
weight: 400
|
|
@ -1,22 +0,0 @@
|
|||||||
notifications:
|
|
||||||
- loud: true
|
|
||||||
message: >-
|
|
||||||
Register to join us online for our next community dev meeting, every other
|
|
||||||
Wednesday at 9am-10am PT!
|
|
||||||
published: false
|
|
||||||
title: Netlify CMS Development Planning Sessions Promo
|
|
||||||
url: >-
|
|
||||||
https://www.eventbrite.com/e/netlify-cms-planning-session-bi-weekly-tickets-35794058994
|
|
||||||
- loud: true
|
|
||||||
message: >-
|
|
||||||
We have a community on Gitter - join now to ask questions and discuss the
|
|
||||||
project with other devs!
|
|
||||||
published: false
|
|
||||||
title: Gitter shoutout
|
|
||||||
url: 'https://gitter.im/netlify/netlifycms'
|
|
||||||
- loud: true
|
|
||||||
message: >-
|
|
||||||
Netlify CMS now supports GitLab!
|
|
||||||
published: true
|
|
||||||
title: GitLab announcement
|
|
||||||
url: '/blog/2018/06/netlify-cms-now-supports-gitlab-as-a-backend/'
|
|
@ -1,46 +0,0 @@
|
|||||||
{{ partial "header" . }}
|
|
||||||
{{ $activePage := .Params.position }}
|
|
||||||
|
|
||||||
<div class="docs page">
|
|
||||||
<div class="container">
|
|
||||||
<aside id="sidebar" class="sidebar">
|
|
||||||
<nav id="docs-nav" class="docs-nav" id="docs-nav">
|
|
||||||
{{ $currentPage := . }}
|
|
||||||
{{ range $index, $element := .Site.Menus.docs }}
|
|
||||||
{{ if .HasChildren }}
|
|
||||||
<div class="docs-nav-section">
|
|
||||||
<div class="docs-nav-section-title">{{ .Title }}</div>
|
|
||||||
<ul class="docs-nav-section-list">
|
|
||||||
{{ range .Children }}
|
|
||||||
<a href="{{ .URL }}" class="nav-link {{ if $currentPage.IsMenuCurrent "docs" . }}active{{ end }}">{{ .Title }}</a>
|
|
||||||
{{ end }}
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
{{ end }}
|
|
||||||
{{ end }}
|
|
||||||
</nav>
|
|
||||||
<div class="mobile docs-nav">
|
|
||||||
<select class="btn-primary" id="mobile-docs-nav">
|
|
||||||
<option value="" selected="selected">Select A Topic</option>
|
|
||||||
{{ range $index, $element := .Site.Menus.docs }}
|
|
||||||
{{ if .HasChildren }}
|
|
||||||
<optgroup label="{{ .Title }}"/>
|
|
||||||
{{ range .Children }}
|
|
||||||
<option value="{{ .URL }}" class="nav-link {{ if $currentPage.IsMenuCurrent "docs" . }}active{{ end }}">{{ .Title }}</option>
|
|
||||||
{{ end }}
|
|
||||||
{{ end }}
|
|
||||||
{{ end }}
|
|
||||||
</select>
|
|
||||||
</div>
|
|
||||||
</aside>
|
|
||||||
<article class="docs-content" id="docs-content">
|
|
||||||
{{ partial "edit-link" . }}
|
|
||||||
{{ .Content }}
|
|
||||||
{{- if eq .Title "Widgets" -}} <!-- Check if is widgets page, if so, add the partial "widgets" for the widget cloud functionality -->
|
|
||||||
{{- partial "widgets" . -}}
|
|
||||||
{{- end -}}
|
|
||||||
</article>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
{{ partial "footer" . }}
|
|
@ -1,16 +0,0 @@
|
|||||||
{{ partial "header" . }}
|
|
||||||
|
|
||||||
<div class="docs page">
|
|
||||||
<div class="container">
|
|
||||||
<article class="blog-content" id="blog-content">
|
|
||||||
<div class="blog-post-header">
|
|
||||||
<h1>{{ .Title }}</h1>
|
|
||||||
<p class="meta-info">by {{ .Params.author }} on {{ .Date.Format "January 2, 2006" }}</p>
|
|
||||||
</div>
|
|
||||||
{{ .Content }}
|
|
||||||
</article>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
{{ partial "footer" . }}
|
|
||||||
|
|
@ -1,88 +0,0 @@
|
|||||||
{{ partial "header" . }}
|
|
||||||
|
|
||||||
<div class="landing page">
|
|
||||||
<section class="landing hero">
|
|
||||||
<div class="contained">
|
|
||||||
|
|
||||||
<div class="hero-copy">
|
|
||||||
<h1 class="headline">{{ .Site.Data.landing.hero.headline | markdownify }}</h1>
|
|
||||||
<span class="subhead">{{ .Site.Data.landing.hero.subhead | markdownify }}</span>
|
|
||||||
<span class="cta-header">{{ .Site.Data.landing.cta.button | markdownify }}</span>
|
|
||||||
</div>
|
|
||||||
<div class="hero-features">
|
|
||||||
{{ range $index, $id := .Site.Data.landing.hero.devfeatures }}
|
|
||||||
<div class="feature">
|
|
||||||
<h3>{{ .feature | markdownify }}</h3>
|
|
||||||
<p>{{ .description | markdownify }}</p>
|
|
||||||
</div>
|
|
||||||
{{ end }}
|
|
||||||
</div>
|
|
||||||
<a class="hero-graphic">
|
|
||||||
<img src="/img/screenshot-editor.jpg" class="responsive"/>
|
|
||||||
<div class="hero-videolink">▶</div>
|
|
||||||
</a>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
</section>
|
|
||||||
|
|
||||||
<section class="cta">
|
|
||||||
<div class="cta-primary">
|
|
||||||
<p><span class="hook">{{ .Site.Data.landing.cta.primaryhook | markdownify }}</span> {{ .Site.Data.landing.cta.primary | markdownify }}</p>{{ .Site.Data.landing.cta.button | markdownify }}
|
|
||||||
</div>
|
|
||||||
</section>
|
|
||||||
|
|
||||||
<section class="whatsnew">
|
|
||||||
<div class="contained">
|
|
||||||
<ol>
|
|
||||||
{{ range .Site.Data.updates }}
|
|
||||||
{{ range first 3 . }}
|
|
||||||
<a href="https://github.com/netlify/netlify-cms/releases/tag/{{ .version }}"><li><div class="update-metadata"><span class="update-version">{{ .version }}</span><span class="update-date">{{ dateFormat "January 2, 2006" .date }}</span></div><span class="update-description">{{ .description | markdownify }}</span></li></a>
|
|
||||||
{{ end }}
|
|
||||||
{{ end }}
|
|
||||||
</ol>
|
|
||||||
</div>
|
|
||||||
</section>
|
|
||||||
|
|
||||||
<section class="editors">
|
|
||||||
<div class="contained">
|
|
||||||
<h2>{{ .Site.Data.landing.editors.hook | markdownify }}</h2>
|
|
||||||
<p id="editor-intro">{{ .Site.Data.landing.editors.intro | markdownify }}</p>
|
|
||||||
<div class="editors-features">
|
|
||||||
{{ range $index, $id := .Site.Data.landing.editors.features }}
|
|
||||||
<div class="feature">
|
|
||||||
<img src="{{ .imgpath }}" >
|
|
||||||
<h3>{{ .feature | markdownify }}</h3>
|
|
||||||
<p>{{ .description | markdownify }}</p>
|
|
||||||
</div>
|
|
||||||
{{ end }}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</section>
|
|
||||||
|
|
||||||
<section class="communitysupport">
|
|
||||||
<div class="contained">
|
|
||||||
<h2>{{ .Site.Data.landing.community.hook | markdownify }}</h2>
|
|
||||||
<div class="community">
|
|
||||||
<div class="community-features">
|
|
||||||
{{ range $index, $id := .Site.Data.landing.community.features }}
|
|
||||||
<div class="feature">
|
|
||||||
<h3>{{ .feature | markdownify }}</h3>
|
|
||||||
<p>{{ .description | markdownify }}</p>
|
|
||||||
</div>
|
|
||||||
{{ end }}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="contributors feature">
|
|
||||||
<h3>{{ .Site.Data.landing.community.contributors | markdownify }}</h3>
|
|
||||||
{{ range .Site.Data.contributors }}
|
|
||||||
<div class="contributor-list">
|
|
||||||
{{ range . }}
|
|
||||||
<a href="{{.profile}}" title="{{.name}}"><img src="{{.avatar_url}}" alt="{{.login}}" /></a>
|
|
||||||
{{ end }}
|
|
||||||
</div>
|
|
||||||
{{ end }}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</section>
|
|
||||||
|
|
||||||
{{ partial "footer" . }}
|
|
@ -1,38 +0,0 @@
|
|||||||
{{ partial "header" . }}
|
|
||||||
|
|
||||||
<div class="community page">
|
|
||||||
<section class="community hero">
|
|
||||||
<div class="contained">
|
|
||||||
|
|
||||||
<div class="hero-copy">
|
|
||||||
<h1 class="headline">{{ .Params.headline | markdownify }}</h1>
|
|
||||||
<h2 class="subhead">{{ .Params.subhead | markdownify }}</h2>
|
|
||||||
<h3 class="ctas"><ul><li>{{ .Params.primarycta | markdownify }}</li></ul></h3>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="calendar-cta">
|
|
||||||
<h2>{{ .Params.upcomingevent.hook }}</h2>
|
|
||||||
<div class="calendar">
|
|
||||||
<div class="month"></div>
|
|
||||||
<div class="day"></div>
|
|
||||||
</div>
|
|
||||||
<h3><strong></strong> at <strong></strong></h3>
|
|
||||||
<div class="cal-cta">{{ .Params.primarycta | markdownify }}</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
</section>
|
|
||||||
|
|
||||||
<section class="how-it-works clearfix">
|
|
||||||
<div class="contained">
|
|
||||||
<div class="half">
|
|
||||||
<h4 class="section-label">How it works</h4>
|
|
||||||
<p>{{ .Params.howitworks | markdownify }}</p>
|
|
||||||
<h4 class="section-label">How to join</h4>
|
|
||||||
<p>{{ .Params.howtojoin | markdownify }}</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</section>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
{{ partial "footer" . }}
|
|
@ -1,10 +0,0 @@
|
|||||||
<a class="edit-this-page" href="https://github.com/netlify/netlify-cms/blob/master/website/site/content/{{ .File.Path }}">
|
|
||||||
<svg version="1.1" id="pencil" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
|
||||||
width="14px" height="14px" viewBox="0 0 512 512" enable-background="new 0 0 512 512" xml:space="preserve">
|
|
||||||
<path d="M398.875,248.875L172.578,475.187l-22.625-22.625L376.25,226.265L398.875,248.875z M308.375,158.39L82.063,384.687
|
|
||||||
l45.266,45.25L353.625,203.64L308.375,158.39z M263.094,113.125L36.828,339.437l22.625,22.625L285.75,135.765L263.094,113.125z
|
|
||||||
M308.375,67.875L285.719,90.5L421.5,226.265l22.625-22.625L308.375,67.875z M376.25,0L331,45.25l135.75,135.766L512,135.781
|
|
||||||
L376.25,0z M32,453.5V480h26.5L32,453.5 M0,376.25L135.766,512H0V376.25L0,376.25z"/>
|
|
||||||
</svg>
|
|
||||||
Edit this page
|
|
||||||
</a>
|
|
@ -1,46 +0,0 @@
|
|||||||
<footer>
|
|
||||||
<div class="contained">
|
|
||||||
<div class="social-buttons">
|
|
||||||
{{ range $index, $id := .Site.Data.global.footer.buttons }}
|
|
||||||
<a href="{{ .url }}">{{ .name }}</a>
|
|
||||||
{{ end }}
|
|
||||||
</div>
|
|
||||||
<div class="footer-info">
|
|
||||||
<p><a href="https://github.com/netlify/netlify-cms/blob/master/LICENSE" class="text-link">Distributed under MIT License</a> ·
|
|
||||||
<a href="https://github.com/netlify/netlify-cms/blob/master/CODE_OF_CONDUCT.md" class="text-link">Code of Conduct</a></p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</footer>
|
|
||||||
|
|
||||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
|
|
||||||
{{ if or (eq .Section "docs") (eq .Title "Docs") }}
|
|
||||||
<script src="/jquery.scrollTo.min.js"></script>
|
|
||||||
<script src="/jquery.localScroll.min.js"></script>
|
|
||||||
<script src="/prism.js"></script>
|
|
||||||
{{ end }}
|
|
||||||
{{ if eq .Title "Community" }}
|
|
||||||
<script src="/moment.min.js"></script>
|
|
||||||
{{ end }}
|
|
||||||
<script src="/app.js"></script>
|
|
||||||
<script type="text/javascript" src="https://cdn.jsdelivr.net/docsearch.js/2/docsearch.min.js"></script>
|
|
||||||
<script type="text/javascript"> docsearch({
|
|
||||||
apiKey: '08d03dc80862e84c70c5a1e769b13019',
|
|
||||||
indexName: 'netlifycms',
|
|
||||||
inputSelector: '.algolia-search',
|
|
||||||
debug: false // Set debug to true if you want to inspect the dropdown
|
|
||||||
});
|
|
||||||
</script>
|
|
||||||
{{- if eq .Title "Widgets" -}} <!-- Check if is widgets page, if so, add the widget cloud js script -->
|
|
||||||
<script src="/widgets.js"></script>
|
|
||||||
{{- end -}}
|
|
||||||
<script async defer src="https://buttons.github.io/buttons.js"></script>
|
|
||||||
{{ if or (eq .Section "docs") (eq .Title "Docs") (eq .Title "Community") }}
|
|
||||||
<script>
|
|
||||||
((window.gitter = {}).chat = {}).options = {
|
|
||||||
room: 'netlify/NetlifyCMS'
|
|
||||||
};
|
|
||||||
</script>
|
|
||||||
<script src="https://sidecar.gitter.im/dist/sidecar.v1.js" async defer></script>
|
|
||||||
{{ end }}
|
|
||||||
</body>
|
|
||||||
</html>
|
|
@ -1,63 +0,0 @@
|
|||||||
<!doctype html>
|
|
||||||
<html>
|
|
||||||
<head>
|
|
||||||
<title>{{ .Site.Title }}</title>
|
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
||||||
<link rel="apple-touch-icon" sizes="180x180" href="/img/favicon/apple-touch-icon.png">
|
|
||||||
<link rel="icon" type="image/png" href="/img/favicon/favicon-32x32.png" sizes="32x32">
|
|
||||||
<link rel="icon" type="image/png" href="/img/favicon/favicon-16x16.png" sizes="16x16">
|
|
||||||
<link rel="manifest" href="/img/favicon/manifest.json">
|
|
||||||
<link rel="mask-icon" href="/img/favicon/safari-pinned-tab.svg" color="#96cf05">
|
|
||||||
<meta name="apple-mobile-web-app-title" content="NetlifyCMS">
|
|
||||||
<meta name="application-name" content="NetlifyCMS">
|
|
||||||
<meta name="theme-color" content="#ffffff">
|
|
||||||
<link rel="stylesheet" href="/css/main.css"/>
|
|
||||||
|
|
||||||
<meta name="description" content=
|
|
||||||
{{ if .Params.meta_description }}
|
|
||||||
{{ .Params.meta_description }}
|
|
||||||
{{ else if .Params.description }}
|
|
||||||
{{ .Params.description }}
|
|
||||||
{{ else if or (eq .Section "blog") (eq .Title "Blog") }}
|
|
||||||
"Recent news and updates about Netlify CMS."
|
|
||||||
{{ else }}
|
|
||||||
"Netlify CMS provides open source content management for your Git workflow."
|
|
||||||
{{ end }}
|
|
||||||
>
|
|
||||||
|
|
||||||
{{ if or (eq .Section "docs") (eq .Title "Docs") }}
|
|
||||||
<link rel="stylesheet" href="/css/lib/prism.css"/>
|
|
||||||
{{ end }}
|
|
||||||
<link rel="stylesheet" href="https://cdn.jsdelivr.net/docsearch.js/2/docsearch.min.css" />
|
|
||||||
{{ range .AlternativeOutputFormats -}}
|
|
||||||
{{ printf `<link rel="%s" type="%s+%s" href="%s" title="%s" />` .Rel .MediaType.Type .MediaType.Suffix .Permalink $.Site.Title | safeHTML }}
|
|
||||||
{{ end -}}
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
{{ range .Site.Data.notifications }}
|
|
||||||
{{ range . }}
|
|
||||||
{{ if .published }}
|
|
||||||
<a href="{{ .url }}" class="notification {{ if .loud }}notification-loud{{end}}">{{ .message }}</a>
|
|
||||||
{{ end }}
|
|
||||||
{{ end }}
|
|
||||||
{{ end }}
|
|
||||||
<header id="header" class="{{ .Section }}">
|
|
||||||
<div class="contained">
|
|
||||||
<div class="logo-container">
|
|
||||||
<a href="/" class="logo"><img src="/img/netlify-cms-logo.svg"/></a>
|
|
||||||
{{ if or (eq .Section "docs") (eq .Title "Docs") }}
|
|
||||||
<a class="utility-input">
|
|
||||||
<img src="/img/search.svg" />
|
|
||||||
<input type="search" placeholder="Search the docs" class="algolia-search"/>
|
|
||||||
</a>
|
|
||||||
{{ end }}
|
|
||||||
</div>
|
|
||||||
<div class="nav-container">
|
|
||||||
<a class="nav-link docs-link" href="/docs/intro/">Docs</a>
|
|
||||||
<a class="nav-link contributing-link" href="/docs/contributor-guide">Contributing</a>
|
|
||||||
<a class="nav-link" href="/community">Community</a>
|
|
||||||
<a class="nav-link" href="/blog/">Blog</a>
|
|
||||||
<a id="ghstars" class="github-button" href="https://github.com/netlify/netlify-cms" data-icon="octicon-star" data-show-count="true" aria-label="Star netlify/netlify-cms on GitHub">Star</a>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</header>
|
|
@ -1,14 +0,0 @@
|
|||||||
<section class="widgets">
|
|
||||||
<div class="widgets__cloud">
|
|
||||||
{{- range $index, $widget := .Resources -}}
|
|
||||||
<span class="widgets__item {{if eq $index 0}}widgets__item_active{{end}}" data-widget-target="{{.Params.target}}">{{.Params.label}}</span>
|
|
||||||
{{- end -}}
|
|
||||||
</div>
|
|
||||||
<div class="widgets__container">
|
|
||||||
{{- range $index, $widget := .Resources -}}
|
|
||||||
<div class="widget {{if eq $index 0}}widget_open{{end}}" id="{{.Params.target}}">
|
|
||||||
{{.Content}}
|
|
||||||
</div>
|
|
||||||
{{- end -}}
|
|
||||||
</div>
|
|
||||||
</section>
|
|
@ -1,17 +0,0 @@
|
|||||||
{{ partial "header" . }}
|
|
||||||
|
|
||||||
<div class="blog page">
|
|
||||||
<div class="container">
|
|
||||||
<h1>Netlify CMS Blog</h1>
|
|
||||||
{{ range (.Paginate .Data.Pages.ByDate.Reverse ).Pages }}
|
|
||||||
<article class="blog-list-item">
|
|
||||||
<h2><a href="{{ .Permalink }}" class="article">{{ .Title }}</a></h2>
|
|
||||||
<p class="meta-info">by {{ .Params.author }} on {{ .Date.Format "January 2, 2006" }}</p>
|
|
||||||
<p>{{ .Description }}</p>
|
|
||||||
</article>
|
|
||||||
{{ end }}
|
|
||||||
{{ template "_internal/pagination.html" . }}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
{{ partial "footer" . }}
|
|
@ -1,7 +0,0 @@
|
|||||||
/**
|
|
||||||
* Copyright (c) 2007-2016 Ariel Flesler - aflesler<a>gmail<d>com | http://flesler.blogspot.com
|
|
||||||
* Licensed under MIT
|
|
||||||
* @author Ariel Flesler
|
|
||||||
* @version 1.4.0
|
|
||||||
*/
|
|
||||||
;(function(a){if(typeof define==='function'&&define.amd){define(['jquery'],a)}else{a(jQuery)}}(function($){var g=location.href.replace(/#.*/,'');var h=$.localScroll=function(a){$('body').localScroll(a)};h.defaults={duration:1000,axis:'y',event:'click',stop:true,target:window};$.fn.localScroll=function(a){a=$.extend({},h.defaults,a);if(a.hash&&location.hash){if(a.target)window.scrollTo(0,0);scroll(0,location,a)}return a.lazy?this.on(a.event,'a,area',function(e){if(filter.call(this)){scroll(e,this,a)}}):this.find('a,area').filter(filter).bind(a.event,function(e){scroll(e,this,a)}).end().end();function filter(){return!!this.href&&!!this.hash&&this.href.replace(this.hash,'')===g&&(!a.filter||$(this).is(a.filter))}};h.hash=function(){};function scroll(e,a,b){var c=a.hash.slice(1),elem=document.getElementById(c)||document.getElementsByName(c)[0];if(!elem)return;if(e)e.preventDefault();var d=$(b.target);if(b.lock&&d.is(':animated')||b.onBefore&&b.onBefore(e,elem,d)===false)return;if(b.stop){d.stop(true)}if(b.hash){var f=elem.id===c?'id':'name',$a=$('<a> </a>').attr(f,c).css({position:'absolute',top:$(window).scrollTop(),left:$(window).scrollLeft()});elem[f]='';$('body').prepend($a);location.hash=a.hash;$a.remove();elem[f]=c}d.scrollTo(elem,b).trigger('notify.serialScroll',[elem])}return h}));
|
|
7
website/site/static/jquery.scrollTo.min.js
vendored
@ -1,7 +0,0 @@
|
|||||||
/**
|
|
||||||
* Copyright (c) 2007-2015 Ariel Flesler - aflesler<a>gmail<d>com | http://flesler.blogspot.com
|
|
||||||
* Licensed under MIT
|
|
||||||
* @author Ariel Flesler
|
|
||||||
* @version 2.1.0
|
|
||||||
*/
|
|
||||||
;(function(l){'use strict';l(['jquery'],function($){var k=$.scrollTo=function(a,b,c){return $(window).scrollTo(a,b,c)};k.defaults={axis:'xy',duration:0,limit:true};function isWin(a){return!a.nodeName||$.inArray(a.nodeName.toLowerCase(),['iframe','#document','html','body'])!==-1}$.fn.scrollTo=function(f,g,h){if(typeof g==='object'){h=g;g=0}if(typeof h==='function'){h={onAfter:h}}if(f==='max'){f=9e9}h=$.extend({},k.defaults,h);g=g||h.duration;var j=h.queue&&h.axis.length>1;if(j){g/=2}h.offset=both(h.offset);h.over=both(h.over);return this.each(function(){if(f===null)return;var d=isWin(this),elem=d?this.contentWindow||window:this,$elem=$(elem),targ=f,attr={},toff;switch(typeof targ){case'number':case'string':if(/^([+-]=?)?\d+(\.\d+)?(px|%)?$/.test(targ)){targ=both(targ);break}targ=d?$(targ):$(targ,elem);if(!targ.length)return;case'object':if(targ.is||targ.style){toff=(targ=$(targ)).offset()}}var e=$.isFunction(h.offset)&&h.offset(elem,targ)||h.offset;$.each(h.axis.split(''),function(i,a){var b=a==='x'?'Left':'Top',pos=b.toLowerCase(),key='scroll'+b,prev=$elem[key](),max=k.max(elem,a);if(toff){attr[key]=toff[pos]+(d?0:prev-$elem.offset()[pos]);if(h.margin){attr[key]-=parseInt(targ.css('margin'+b),10)||0;attr[key]-=parseInt(targ.css('border'+b+'Width'),10)||0}attr[key]+=e[pos]||0;if(h.over[pos]){attr[key]+=targ[a==='x'?'width':'height']()*h.over[pos]}}else{var c=targ[pos];attr[key]=c.slice&&c.slice(-1)==='%'?parseFloat(c)/100*max:c}if(h.limit&&/^\d+$/.test(attr[key])){attr[key]=attr[key]<=0?0:Math.min(attr[key],max)}if(!i&&h.axis.length>1){if(prev===attr[key]){attr={}}else if(j){animate(h.onAfterFirst);attr={}}}});animate(h.onAfter);function animate(a){var b=$.extend({},h,{queue:true,duration:g,complete:a&&function(){a.call(elem,targ,h)}});$elem.animate(attr,b)}})};k.max=function(a,b){var c=b==='x'?'Width':'Height',scroll='scroll'+c;if(!isWin(a))return a[scroll]-$(a)[c.toLowerCase()]();var d='client'+c,doc=a.ownerDocument||a.document,html=doc.documentElement,body=doc.body;return Math.max(html[scroll],body[scroll])-Math.min(html[d],body[d])};function both(a){return $.isFunction(a)||$.isPlainObject(a)?a:{top:a,left:a}}$.Tween.propHooks.scrollLeft=$.Tween.propHooks.scrollTop={get:function(t){return $(t.elem)[t.prop]()},set:function(t){var a=this.get(t);if(t.options.interrupt&&t._last&&t._last!==a){return $(t.elem).stop()}var b=Math.round(t.now);if(a!==b){$(t.elem)[t.prop](b);t._last=this.get(t)}}};return k})}(typeof define==='function'&&define.amd?define:function(a,b){'use strict';if(typeof module!=='undefined'&&module.exports){module.exports=b(require('jquery'))}else{b(jQuery)}}));
|
|
7
website/site/static/moment.min.js
vendored
@ -1,76 +0,0 @@
|
|||||||
// Widgets section
|
|
||||||
function widgetsCloud() {
|
|
||||||
|
|
||||||
const widgetItems = document.getElementsByClassName("widgets__item"), // Widget word cloud
|
|
||||||
widgets = document.getElementsByClassName("widget"); // Widgets' bodies
|
|
||||||
let activeWidgetItem = document.getElementsByClassName("widgets__item_active")[0]; // Active button in the widgets cloud
|
|
||||||
|
|
||||||
if (document.getElementsByClassName("widgets")) {
|
|
||||||
|
|
||||||
if (loadWidgetFromHash()) { // Scroll to widget cloud if URL hash set to a widget.
|
|
||||||
setTimeout(() => {
|
|
||||||
document.getElementsByClassName("widgets")[0].scrollIntoView({
|
|
||||||
behavior: "smooth",
|
|
||||||
block: "nearest"
|
|
||||||
}); // Scrolls to the widgets section
|
|
||||||
}, 200);
|
|
||||||
}
|
|
||||||
window.addEventListener('hashchange', loadWidgetFromHash);
|
|
||||||
|
|
||||||
for (let i = 0; i < widgetItems.length; i++) {
|
|
||||||
widgetItems[i].addEventListener("click", e => { // Add click event for each widget button in the cloud
|
|
||||||
const targetWidget = document.getElementById(e.target.dataset.widgetTarget), // Defines which widget the user is trying to render
|
|
||||||
openedWidget = document.getElementsByClassName("widget_open")[0], // Defines the current open widget
|
|
||||||
targetWidgetItem = e.target; // Defines the current open widget
|
|
||||||
changeWidgets(openedWidget, targetWidget, targetWidgetItem); // Runs the function to change which widget is displayed
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
function loadWidgetFromHash() {
|
|
||||||
if (!window.location.hash) return; // Check if the given URL has a hash to make each widget shareable
|
|
||||||
|
|
||||||
const targetWidget = document.getElementById(window.location.hash.substr(1)),
|
|
||||||
openedWidget = document.getElementsByClassName("widget_open")[0];
|
|
||||||
|
|
||||||
let targetWidgetItem = "";
|
|
||||||
for (let i = 0; i < widgetItems.length; i++) {
|
|
||||||
if (widgetItems[i].dataset.widgetTarget == window.location.hash.substr(1)) {
|
|
||||||
targetWidgetItem = widgetItems[i]
|
|
||||||
}
|
|
||||||
};
|
|
||||||
if (!targetWidgetItem) return; // Make sure the hash pointed to a widget, not something else.
|
|
||||||
|
|
||||||
changeWidgets(openedWidget, targetWidget, targetWidgetItem, true); // Runs the function to change which widget is displayed
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
function changeWidgets(active, target, cloudItem, preventHistoryUpdate) {
|
|
||||||
|
|
||||||
target.classList.add("widget_opening"); // Starts the process of opening the next widget
|
|
||||||
|
|
||||||
active.classList.remove("widget_open"); // Removes the active state of the current widget
|
|
||||||
active.classList.add("widget_closing"); // But guarantees the current active widget a closing class for transition purposes
|
|
||||||
|
|
||||||
activeWidgetItem.classList.remove("widgets__item_active"); // Removes the active state of the current widget item in the cloud
|
|
||||||
activeWidgetItem = cloudItem; // Sets the new active widget item as the clicked one
|
|
||||||
activeWidgetItem.classList.add("widgets__item_active"); // And adds the active CSS class to it
|
|
||||||
|
|
||||||
if (!preventHistoryUpdate) {
|
|
||||||
if (history.pushState) {
|
|
||||||
history.pushState(null, null, '#' + cloudItem.dataset.widgetTarget);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
location.hash = '#' + cloudItem.dataset.widgetTarget;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
setTimeout(() => {
|
|
||||||
target.classList.remove("widget_opening"); // Removes the opening class to finish transition
|
|
||||||
target.classList.add("widget_open"); // Defines the new target widget
|
|
||||||
active.classList.remove("widget_closing"); // Finally gets completely rid of the previously openened widget
|
|
||||||
|
|
||||||
}, 150) // When the transition is done, finish the process by attributing the final classes to each widget
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
widgetsCloud();
|
|
70
website/src/components/docs-nav.js
Normal file
@ -0,0 +1,70 @@
|
|||||||
|
import React, { Component } from 'react';
|
||||||
|
import Link from 'gatsby-link';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Maually get table of contents since tableOfContents from markdown
|
||||||
|
* nodes have code added.
|
||||||
|
*
|
||||||
|
* https://github.com/gatsbyjs/gatsby/issues/5436
|
||||||
|
*/
|
||||||
|
class TableOfContents extends Component {
|
||||||
|
state = {
|
||||||
|
headings: []
|
||||||
|
};
|
||||||
|
|
||||||
|
componentDidMount() {
|
||||||
|
const contentHeadings = document.querySelectorAll('.docs-content h2');
|
||||||
|
|
||||||
|
const headings = [];
|
||||||
|
contentHeadings.forEach(h => {
|
||||||
|
headings.push({
|
||||||
|
id: h.id,
|
||||||
|
text: h.innerText
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
this.setState({
|
||||||
|
headings
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
render() {
|
||||||
|
const { headings } = this.state;
|
||||||
|
return (
|
||||||
|
<ul className="nav-subsections">
|
||||||
|
{headings.map(h => (
|
||||||
|
<li key={h.id}>
|
||||||
|
<a href={`#${h.id}`} className="subnav-link">
|
||||||
|
{h.text}
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
))}
|
||||||
|
</ul>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const DocsNav = ({ items, location }) => (
|
||||||
|
<nav className="docs-nav" id="docs-nav">
|
||||||
|
{items.map(item => (
|
||||||
|
<div className="docs-nav-section" key={item.title}>
|
||||||
|
<div className="docs-nav-section-title">{item.title}</div>
|
||||||
|
<ul className="docs-nav-section-list">
|
||||||
|
{item.group.edges.map(({ node }) => (
|
||||||
|
<li className="docs-nav-item" key={node.fields.slug}>
|
||||||
|
<Link
|
||||||
|
to={node.fields.slug}
|
||||||
|
className="nav-link"
|
||||||
|
activeClassName="active">
|
||||||
|
{node.frontmatter.title}
|
||||||
|
</Link>
|
||||||
|
{location.pathname === node.fields.slug && <TableOfContents />}
|
||||||
|
</li>
|
||||||
|
))}
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
))}
|
||||||
|
</nav>
|
||||||
|
);
|
||||||
|
|
||||||
|
export default DocsNav;
|
39
website/src/components/docsearch.js
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
import React, { Component } from 'react';
|
||||||
|
|
||||||
|
import searchIcon from '../img/search.svg';
|
||||||
|
|
||||||
|
class DocSearch extends Component {
|
||||||
|
state = {
|
||||||
|
enabled: true
|
||||||
|
};
|
||||||
|
componentDidMount() {
|
||||||
|
if (window.docsearch) {
|
||||||
|
window.docsearch({
|
||||||
|
apiKey: '08d03dc80862e84c70c5a1e769b13019',
|
||||||
|
indexName: 'netlifycms',
|
||||||
|
inputSelector: '.algolia-search',
|
||||||
|
debug: false // Set debug to true if you want to inspect the dropdown
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
this.setState({ enabled: false });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
render() {
|
||||||
|
if (!this.state.enabled) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<a className="utility-input">
|
||||||
|
<img src={searchIcon} />
|
||||||
|
<input
|
||||||
|
type="search"
|
||||||
|
placeholder="Search the docs"
|
||||||
|
className="algolia-search"
|
||||||
|
/>
|
||||||
|
</a>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default DocSearch;
|
30
website/src/components/edit-link.js
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
import React from 'react';
|
||||||
|
|
||||||
|
const EditLink = ({ path }) => (
|
||||||
|
<a
|
||||||
|
className="edit-this-page"
|
||||||
|
href={`https://github.com/netlify/netlify-cms/blob/master/website/content/${path}`}>
|
||||||
|
<svg
|
||||||
|
version="1.1"
|
||||||
|
id="pencil"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
xmlnsXlink="http://www.w3.org/1999/xlink"
|
||||||
|
x="0px"
|
||||||
|
y="0px"
|
||||||
|
width="14px"
|
||||||
|
height="14px"
|
||||||
|
viewBox="0 0 512 512"
|
||||||
|
enableBackground="new 0 0 512 512"
|
||||||
|
xmlSpace="preserve">
|
||||||
|
<path
|
||||||
|
d="M398.875,248.875L172.578,475.187l-22.625-22.625L376.25,226.265L398.875,248.875z M308.375,158.39L82.063,384.687
|
||||||
|
l45.266,45.25L353.625,203.64L308.375,158.39z M263.094,113.125L36.828,339.437l22.625,22.625L285.75,135.765L263.094,113.125z
|
||||||
|
M308.375,67.875L285.719,90.5L421.5,226.265l22.625-22.625L308.375,67.875z M376.25,0L331,45.25l135.75,135.766L512,135.781
|
||||||
|
L376.25,0z M32,453.5V480h26.5L32,453.5 M0,376.25L135.766,512H0V376.25L0,376.25z"
|
||||||
|
/>
|
||||||
|
</svg>{' '}
|
||||||
|
Edit this page
|
||||||
|
</a>
|
||||||
|
);
|
||||||
|
|
||||||
|
export default EditLink;
|
71
website/src/components/event-widget.js
Normal file
@ -0,0 +1,71 @@
|
|||||||
|
import React, { Component } from 'react';
|
||||||
|
import moment from 'moment';
|
||||||
|
|
||||||
|
class EventWidget extends Component {
|
||||||
|
state = {
|
||||||
|
loading: false,
|
||||||
|
eventDate: ''
|
||||||
|
};
|
||||||
|
|
||||||
|
componentDidMount() {
|
||||||
|
const eventbriteToken = 'C5PX65CJBVIXWWLNFKLO';
|
||||||
|
const eventbriteOrganiser = '14281996019';
|
||||||
|
|
||||||
|
const url = `https://www.eventbriteapi.com/v3/events/search/?token=${eventbriteToken}&organizer.id=${eventbriteOrganiser}&expand=venue%27`;
|
||||||
|
|
||||||
|
this.setState({
|
||||||
|
loading: true
|
||||||
|
});
|
||||||
|
|
||||||
|
fetch(url)
|
||||||
|
.then(res => res.json())
|
||||||
|
.then(data => {
|
||||||
|
const eventDate = data.events[0].start.utc;
|
||||||
|
|
||||||
|
this.setState({
|
||||||
|
loading: false,
|
||||||
|
eventDate
|
||||||
|
});
|
||||||
|
})
|
||||||
|
.catch(err => {
|
||||||
|
console.log(err);
|
||||||
|
// TODO: set state to show error message
|
||||||
|
this.setState({
|
||||||
|
loading: false
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
render() {
|
||||||
|
const { loading, eventDate } = this.state;
|
||||||
|
|
||||||
|
if (loading) {
|
||||||
|
return <span>Loading...</span>;
|
||||||
|
}
|
||||||
|
|
||||||
|
const eventDateMoment = moment(eventDate);
|
||||||
|
|
||||||
|
const offset = eventDateMoment.isDST() ? -7 : -8;
|
||||||
|
|
||||||
|
const month = eventDateMoment.format('MMMM');
|
||||||
|
const day = eventDateMoment.format('DD');
|
||||||
|
|
||||||
|
const datePrefix = eventDateMoment.format('dddd, MMMM Do');
|
||||||
|
const dateSuffix = eventDateMoment.utcOffset(offset).format('h a');
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
<div className="calendar">
|
||||||
|
<div className="month">{month}</div>
|
||||||
|
<div className="day">{day}</div>
|
||||||
|
</div>
|
||||||
|
<h3>
|
||||||
|
<strong>
|
||||||
|
{datePrefix} at {dateSuffix} PT
|
||||||
|
</strong>
|
||||||
|
</h3>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default EventWidget;
|
36
website/src/components/footer.js
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
import React from 'react';
|
||||||
|
|
||||||
|
import '../css/imports/footer.css';
|
||||||
|
|
||||||
|
const Footer = ({ buttons }) => (
|
||||||
|
<footer>
|
||||||
|
<div className="contained">
|
||||||
|
<div className="social-buttons">
|
||||||
|
{buttons.map(btn => (
|
||||||
|
<a href={btn.url} key={btn.url}>
|
||||||
|
{btn.name}
|
||||||
|
</a>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
<div className="footer-info">
|
||||||
|
<p>
|
||||||
|
<a
|
||||||
|
href="https://github.com/netlify/netlify-cms/blob/master/LICENSE"
|
||||||
|
className="text-link"
|
||||||
|
>
|
||||||
|
Distributed under MIT License
|
||||||
|
</a>{' '}
|
||||||
|
·{' '}
|
||||||
|
<a
|
||||||
|
href="https://github.com/netlify/netlify-cms/blob/master/CODE_OF_CONDUCT.md"
|
||||||
|
className="text-link"
|
||||||
|
>
|
||||||
|
Code of Conduct
|
||||||
|
</a>
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</footer>
|
||||||
|
);
|
||||||
|
|
||||||
|
export default Footer;
|
94
website/src/components/header.js
Normal file
@ -0,0 +1,94 @@
|
|||||||
|
import React, { Component } from 'react';
|
||||||
|
import Link from 'gatsby-link';
|
||||||
|
import classnames from 'classnames';
|
||||||
|
|
||||||
|
import DocSearch from './docsearch';
|
||||||
|
|
||||||
|
import logo from '../img/netlify-cms-logo.svg';
|
||||||
|
|
||||||
|
import '../css/imports/header.css';
|
||||||
|
|
||||||
|
class Header extends Component {
|
||||||
|
state = {
|
||||||
|
scrolled: false
|
||||||
|
};
|
||||||
|
|
||||||
|
componentDidMount() {
|
||||||
|
// TODO: use raf to throttle events
|
||||||
|
window.addEventListener('scroll', this.handleScroll);
|
||||||
|
}
|
||||||
|
|
||||||
|
componentWillUnmount() {
|
||||||
|
window.removeEventListener('scroll', this.handleScroll);
|
||||||
|
}
|
||||||
|
|
||||||
|
handleScroll = event => {
|
||||||
|
const currentWindowPos =
|
||||||
|
document.documentElement.scrollTop || document.body.scrollTop;
|
||||||
|
|
||||||
|
const scrolled = currentWindowPos > 0;
|
||||||
|
|
||||||
|
this.setState({
|
||||||
|
scrolled
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
render() {
|
||||||
|
const { location } = this.props;
|
||||||
|
const { scrolled } = this.state;
|
||||||
|
|
||||||
|
const isDocs = location.pathname.indexOf('docs') !== -1;
|
||||||
|
const isBlog = location.pathname.indexOf('blog') !== -1;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<header
|
||||||
|
id="header"
|
||||||
|
className={classnames({
|
||||||
|
docs: isDocs,
|
||||||
|
blog: isBlog,
|
||||||
|
scrolled
|
||||||
|
})}
|
||||||
|
>
|
||||||
|
<div className="contained">
|
||||||
|
<div className="logo-container">
|
||||||
|
<Link to="/" className="logo">
|
||||||
|
<img src={logo} />
|
||||||
|
</Link>
|
||||||
|
{isDocs && <DocSearch />}
|
||||||
|
</div>
|
||||||
|
<div className="nav-container">
|
||||||
|
<Link className="nav-link docs-link" to="/docs/intro">
|
||||||
|
Docs
|
||||||
|
</Link>
|
||||||
|
<Link
|
||||||
|
className="nav-link contributing-link"
|
||||||
|
to="/docs/contributor-guide"
|
||||||
|
>
|
||||||
|
Contributing
|
||||||
|
</Link>
|
||||||
|
<Link className="nav-link" to="/community">
|
||||||
|
Community
|
||||||
|
</Link>
|
||||||
|
<Link className="nav-link" to="/blog">
|
||||||
|
Blog
|
||||||
|
</Link>
|
||||||
|
<span className="gh-button">
|
||||||
|
<a
|
||||||
|
id="ghstars"
|
||||||
|
className="github-button"
|
||||||
|
href="https://github.com/netlify/netlify-cms"
|
||||||
|
data-icon="octicon-star"
|
||||||
|
data-show-count="true"
|
||||||
|
aria-label="Star netlify/netlify-cms on GitHub"
|
||||||
|
>
|
||||||
|
Star
|
||||||
|
</a>
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</header>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default Header;
|
11
website/src/components/markdownify.js
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
import React, { Fragment } from 'react';
|
||||||
|
import Markdown from 'react-markdown';
|
||||||
|
|
||||||
|
const Markdownify = ({ source }) => (
|
||||||
|
<Markdown
|
||||||
|
source={source}
|
||||||
|
renderers={{ root: Fragment, paragraph: Fragment }}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
|
||||||
|
export default Markdownify;
|
32
website/src/components/mobile-nav.js
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
import React, { Component } from 'react';
|
||||||
|
|
||||||
|
class MobileNav extends Component {
|
||||||
|
handleChange = event => {
|
||||||
|
this.props.history.push(event.target.value);
|
||||||
|
};
|
||||||
|
render() {
|
||||||
|
const { items } = this.props;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="mobile docs-nav">
|
||||||
|
<select className="btn-primary" onChange={this.handleChange}>
|
||||||
|
<option>Select A Topic</option>
|
||||||
|
{items.map(item => (
|
||||||
|
<optgroup label={item.title} key={item.title}>
|
||||||
|
{item.group.edges.map(({ node }) => (
|
||||||
|
<option
|
||||||
|
value={node.fields.slug}
|
||||||
|
key={node.fields.slug}
|
||||||
|
className="nav-link">
|
||||||
|
{node.frontmatter.title}
|
||||||
|
</option>
|
||||||
|
))}
|
||||||
|
</optgroup>
|
||||||
|
))}
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default MobileNav;
|
41
website/src/components/video-embed.js
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
import React, { Component } from 'react';
|
||||||
|
|
||||||
|
import screenshotEditor from '../img/screenshot-editor.jpg';
|
||||||
|
|
||||||
|
class VideoEmbed extends Component {
|
||||||
|
state = {
|
||||||
|
toggled: false
|
||||||
|
};
|
||||||
|
toggleVideo = event => {
|
||||||
|
this.setState({
|
||||||
|
toggled: true
|
||||||
|
});
|
||||||
|
};
|
||||||
|
render() {
|
||||||
|
const { toggled } = this.state;
|
||||||
|
|
||||||
|
const embedcode = (
|
||||||
|
<iframe
|
||||||
|
width={560}
|
||||||
|
height={315}
|
||||||
|
src="https://www.youtube-nocookie.com/embed/p6h-rYSVX90?rel=0&showinfo=0&autoplay=1"
|
||||||
|
frameBorder={0}
|
||||||
|
allow="autoplay; encrypted-media"
|
||||||
|
allowFullScreen
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
|
||||||
|
const imgPlaceholder = (
|
||||||
|
<img src={screenshotEditor} className="responsive" />
|
||||||
|
);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<a className="hero-graphic" onClick={this.toggleVideo}>
|
||||||
|
{toggled ? embedcode : imgPlaceholder}
|
||||||
|
{!toggled && <div className="hero-videolink">▶</div>}
|
||||||
|
</a>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default VideoEmbed;
|
90
website/src/components/widgets.js
Normal file
@ -0,0 +1,90 @@
|
|||||||
|
import React, { Component } from 'react';
|
||||||
|
import classnames from 'classnames';
|
||||||
|
|
||||||
|
import '../css/imports/widgets.css';
|
||||||
|
|
||||||
|
class Widgets extends Component {
|
||||||
|
state = {
|
||||||
|
currentWidget: null
|
||||||
|
};
|
||||||
|
|
||||||
|
componentDidMount() {
|
||||||
|
const { widgets } = this.props;
|
||||||
|
|
||||||
|
const hash = window.location.hash
|
||||||
|
? window.location.hash.replace('#', '')
|
||||||
|
: '';
|
||||||
|
|
||||||
|
const widgetsContainHash = widgets.edges.some(
|
||||||
|
w => w.node.frontmatter.target === hash
|
||||||
|
);
|
||||||
|
|
||||||
|
if (widgetsContainHash) {
|
||||||
|
return this.setState({
|
||||||
|
currentWidget: hash
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
this.setState({
|
||||||
|
currentWidget: widgets.edges[0].node.frontmatter.target
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
handleWidgetChange = (event, target) => {
|
||||||
|
event.preventDefault();
|
||||||
|
this.setState(
|
||||||
|
{
|
||||||
|
currentWidget: target
|
||||||
|
},
|
||||||
|
() => {
|
||||||
|
history.pushState(null, null, `#${target}`);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
render() {
|
||||||
|
const { widgets } = this.props;
|
||||||
|
const { currentWidget } = this.state;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
<section className="widgets">
|
||||||
|
<div className="widgets__cloud">
|
||||||
|
{widgets.edges.map(({ node }) => {
|
||||||
|
const { label, target } = node.frontmatter;
|
||||||
|
return (
|
||||||
|
<button
|
||||||
|
key={target}
|
||||||
|
className={classnames('widgets__item', {
|
||||||
|
widgets__item_active: currentWidget === target
|
||||||
|
})}
|
||||||
|
onClick={event => this.handleWidgetChange(event, target)}
|
||||||
|
>
|
||||||
|
{label}
|
||||||
|
</button>
|
||||||
|
);
|
||||||
|
})}
|
||||||
|
</div>
|
||||||
|
<div className="widgets__container">
|
||||||
|
{widgets.edges.map(({ node }) => {
|
||||||
|
const { label, target } = node.frontmatter;
|
||||||
|
return (
|
||||||
|
<div
|
||||||
|
key={label}
|
||||||
|
className={classnames('widget', {
|
||||||
|
widget_open: currentWidget === target
|
||||||
|
})}
|
||||||
|
>
|
||||||
|
<h3>{label}</h3>
|
||||||
|
<div dangerouslySetInnerHTML={{ __html: node.html }} />
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
})}
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default Widgets;
|
@ -145,6 +145,12 @@ pre {
|
|||||||
line-height: 1 !important;
|
line-height: 1 !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* fixes overflowing code example in widgets */
|
||||||
|
.widget pre {
|
||||||
|
box-sizing: border-box;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
.code,
|
.code,
|
||||||
code {
|
code {
|
||||||
font-family: 'Roboto Mono', monospace !important;
|
font-family: 'Roboto Mono', monospace !important;
|
||||||
|
@ -202,7 +202,6 @@
|
|||||||
h2:not(:first-child) {
|
h2:not(:first-child) {
|
||||||
margin-top: $medium;
|
margin-top: $medium;
|
||||||
}
|
}
|
||||||
|
|
||||||
p {
|
p {
|
||||||
line-height: 1.7;
|
line-height: 1.7;
|
||||||
}
|
}
|
||||||
@ -226,18 +225,13 @@
|
|||||||
border-radius: $borderRadius;
|
border-radius: $borderRadius;
|
||||||
}
|
}
|
||||||
|
|
||||||
code {
|
:not(pre) > code {
|
||||||
|
color: inherit;
|
||||||
background: $lightestGrey;
|
background: $lightestGrey;
|
||||||
border-radius: 2px;
|
border-radius: 2px;
|
||||||
padding: 2px 6px;
|
padding: 2px 6px;
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
}
|
}
|
||||||
|
|
||||||
pre > code {
|
|
||||||
background: initial;
|
|
||||||
padding: initial;
|
|
||||||
white-space: inherit;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.blog-content h1 {
|
.blog-content h1 {
|
||||||
|
@ -15,7 +15,7 @@
|
|||||||
|
|
||||||
em {
|
em {
|
||||||
font-style: normal;
|
font-style: normal;
|
||||||
color: #8B8B8B;
|
color: #8b8b8b;
|
||||||
padding: 0 8px;
|
padding: 0 8px;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -71,7 +71,7 @@ header {
|
|||||||
position: absolute;
|
position: absolute;
|
||||||
padding: $medium 0;
|
padding: $medium 0;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
transition: background .2s ease, padding .2s ease, box-shadow .2s ease;
|
transition: background 0.2s ease, padding 0.2s ease, box-shadow 0.2s ease;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
z-index: 100;
|
z-index: 100;
|
||||||
|
|
||||||
@ -102,14 +102,12 @@ header {
|
|||||||
}
|
}
|
||||||
}*/
|
}*/
|
||||||
|
|
||||||
|
|
||||||
/*.utility-input {
|
/*.utility-input {
|
||||||
@media screen and (max-width: 767px) {
|
@media screen and (max-width: 767px) {
|
||||||
display: block;
|
display: block;
|
||||||
height: $small;
|
height: $small;
|
||||||
margin: $tiny 0 0 0;
|
margin: $tiny 0 0 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@media screen and (min-width: 487px) and (max-width: 767px) {
|
@media screen and (min-width: 487px) and (max-width: 767px) {
|
||||||
margin-top: 32px;
|
margin-top: 32px;
|
||||||
}
|
}
|
||||||
@ -131,7 +129,8 @@ header {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.nav-link + iframe {
|
.gh-button {
|
||||||
|
display: inline-block;
|
||||||
margin-left: $small;
|
margin-left: $small;
|
||||||
vertical-align: middle;
|
vertical-align: middle;
|
||||||
@media screen and (max-width: $mobile) {
|
@media screen and (max-width: $mobile) {
|
||||||
@ -184,7 +183,6 @@ header {
|
|||||||
margin-top: -35px;
|
margin-top: -35px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.utility-input {
|
.utility-input {
|
||||||
@ -194,7 +192,7 @@ header {
|
|||||||
top: -4px;
|
top: -4px;
|
||||||
width: auto;
|
width: auto;
|
||||||
border-radius: 4px;
|
border-radius: 4px;
|
||||||
background-color: rgba(255,255,255,0.1);
|
background-color: rgba(255, 255, 255, 0.1);
|
||||||
color: white;
|
color: white;
|
||||||
margin: 0 0 0 $tiny;
|
margin: 0 0 0 $tiny;
|
||||||
padding-top: -5px;
|
padding-top: -5px;
|
||||||
@ -204,7 +202,7 @@ header {
|
|||||||
font-weight: 600;
|
font-weight: 600;
|
||||||
font-size: 16px;
|
font-size: 16px;
|
||||||
line-height: 24px;
|
line-height: 24px;
|
||||||
transition: all .2s ease-in-out;
|
transition: all 0.2s ease-in-out;
|
||||||
|
|
||||||
@media screen and (min-width: 1024px) {
|
@media screen and (min-width: 1024px) {
|
||||||
display: inline;
|
display: inline;
|
||||||
@ -218,13 +216,17 @@ header {
|
|||||||
&::-webkit-input-placeholder,
|
&::-webkit-input-placeholder,
|
||||||
&:-moz-placeholder,
|
&:-moz-placeholder,
|
||||||
&::-moz-placeholder,
|
&::-moz-placeholder,
|
||||||
&:-ms-input-placeholder {
|
&:-ms-input-placeholder {
|
||||||
font-size: $tiny;
|
font-size: $tiny;
|
||||||
font-weight: $semibold;
|
font-weight: $semibold;
|
||||||
text-align: left;
|
text-align: left;
|
||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
line-height: $small;
|
line-height: $small;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
img {
|
||||||
|
margin-right: 4px;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.logo-container {
|
.logo-container {
|
||||||
|
@ -1,65 +1,71 @@
|
|||||||
.widgets {
|
.widgets {
|
||||||
margin: 2rem 0;
|
margin: 2rem 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.widgets__cloud {
|
.widgets__cloud {
|
||||||
margin: $micro calc(-$micro / 2);
|
margin: $micro calc(-$micro / 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
.widgets__item {
|
.widgets__item {
|
||||||
color: $darkGrey;
|
font-family: inherit;
|
||||||
border: 2px solid $darkGreen;
|
font-size: inherit;
|
||||||
border-radius: $borderRadius;
|
line-height: inherit;
|
||||||
padding: calc($micro /2) $micro;
|
background: transparent;
|
||||||
margin: calc($micro / 2);
|
border: 0;
|
||||||
cursor: pointer;
|
color: $darkGrey;
|
||||||
transition: color .2s ease, background .2s ease;
|
border: 2px solid $darkGreen;
|
||||||
display: inline-block;
|
border-radius: $borderRadius;
|
||||||
font-weight: normal;
|
padding: calc($micro / 2) $micro;
|
||||||
|
margin: calc($micro / 2);
|
||||||
|
cursor: pointer;
|
||||||
|
transition: color 0.2s ease, background 0.2s ease;
|
||||||
|
display: inline-block;
|
||||||
|
font-weight: normal;
|
||||||
}
|
}
|
||||||
|
|
||||||
.widgets__item:hover, .widgets__item_active {
|
.widgets__item:hover,
|
||||||
background: $darkGreen;
|
.widgets__item_active {
|
||||||
color: white !important;
|
background: $darkGreen;
|
||||||
|
color: white !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
.widgets__container {
|
.widgets__container {
|
||||||
margin: 1em 0;
|
margin: 1em 0;
|
||||||
background: $lightGrey;
|
background: $lightGrey;
|
||||||
border-radius: $borderRadius;
|
border-radius: $borderRadius;
|
||||||
transition: height .15s ease;
|
transition: height 0.15s ease;
|
||||||
}
|
}
|
||||||
|
|
||||||
.widget {
|
.widget {
|
||||||
padding: .5em 1em;
|
padding: 0.5em 1em;
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
.widget_open {
|
.widget_open {
|
||||||
display: block;
|
display: block;
|
||||||
}
|
}
|
||||||
|
|
||||||
.widget_closing {
|
.widget_closing {
|
||||||
display: block;
|
display: block;
|
||||||
animation: widgetOpacity .15s ease forwards reverse;
|
animation: widgetOpacity 0.15s ease forwards reverse;
|
||||||
}
|
}
|
||||||
|
|
||||||
.widget_opening {
|
.widget_opening {
|
||||||
display: block;
|
display: block;
|
||||||
position: absolute;
|
position: absolute;
|
||||||
top: 0;
|
top: 0;
|
||||||
left: 0;
|
left: 0;
|
||||||
opacity: 0;
|
opacity: 0;
|
||||||
animation: widgetOpacity .15s .05s ease forwards;
|
animation: widgetOpacity 0.15s 0.05s ease forwards;
|
||||||
}
|
}
|
||||||
|
|
||||||
@keyframes widgetOpacity {
|
@keyframes widgetOpacity {
|
||||||
from {
|
from {
|
||||||
opacity: 0
|
opacity: 0;
|
||||||
}
|
}
|
||||||
to {
|
to {
|
||||||
opacity: 1
|
opacity: 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.widget pre {
|
.widget pre {
|
||||||
@ -68,5 +74,5 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.widget h3 {
|
.widget h3 {
|
||||||
margin-top: 0 !important;
|
margin-top: 0 !important;
|
||||||
}
|
}
|
@ -1,13 +0,0 @@
|
|||||||
@import "imports/base.css";
|
|
||||||
@import "imports/utilities.css";
|
|
||||||
@import "imports/header.css";
|
|
||||||
@import "imports/hero.css";
|
|
||||||
@import "imports/cta.css";
|
|
||||||
@import "imports/whatsnew.css";
|
|
||||||
@import "imports/editors.css";
|
|
||||||
@import "imports/community.css";
|
|
||||||
@import "imports/collab.css";
|
|
||||||
@import "imports/docs.css";
|
|
||||||
@import "imports/widgets.css";
|
|
||||||
@import "imports/footer.css";
|
|
||||||
@import "imports/gitter.css";
|
|
86
website/src/html.js
Normal file
@ -0,0 +1,86 @@
|
|||||||
|
import React from 'react';
|
||||||
|
import Gitter from 'react-sidecar';
|
||||||
|
|
||||||
|
let stylesStr;
|
||||||
|
if (process.env.NODE_ENV === `production`) {
|
||||||
|
try {
|
||||||
|
stylesStr = require('!raw-loader!../public/styles.css');
|
||||||
|
} catch (e) {
|
||||||
|
console.log(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const JS_NPM_URLS = [
|
||||||
|
'https://buttons.github.io/buttons.js',
|
||||||
|
'//unpkg.com/docsearch.js@2.4.1/dist/cdn/docsearch.min.js'
|
||||||
|
];
|
||||||
|
|
||||||
|
module.exports = class HTML extends React.Component {
|
||||||
|
render() {
|
||||||
|
let css;
|
||||||
|
if (process.env.NODE_ENV === 'production') {
|
||||||
|
css = (
|
||||||
|
<style
|
||||||
|
id="gatsby-inlined-css"
|
||||||
|
dangerouslySetInnerHTML={{ __html: stylesStr }}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
const js = JS_NPM_URLS.map(src => <script key={src} src={src} />);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<html {...this.props.htmlAttributes}>
|
||||||
|
<head>
|
||||||
|
<meta charSet="utf-8" />
|
||||||
|
<meta httpEquiv="x-ua-compatible" content="ie=edge" />
|
||||||
|
<meta
|
||||||
|
name="viewport"
|
||||||
|
content="width=device-width, initial-scale=1.0"
|
||||||
|
/>
|
||||||
|
<link
|
||||||
|
rel="apple-touch-icon"
|
||||||
|
sizes="180x180"
|
||||||
|
href="/img/favicon/apple-touch-icon.png"
|
||||||
|
/>
|
||||||
|
<link
|
||||||
|
rel="icon"
|
||||||
|
type="image/png"
|
||||||
|
href="/img/favicon/favicon-32x32.png"
|
||||||
|
sizes="32x32"
|
||||||
|
/>
|
||||||
|
<link
|
||||||
|
rel="icon"
|
||||||
|
type="image/png"
|
||||||
|
href="/img/favicon/favicon-16x16.png"
|
||||||
|
sizes="16x16"
|
||||||
|
/>
|
||||||
|
<link
|
||||||
|
rel="mask-icon"
|
||||||
|
href="/img/favicon/safari-pinned-tab.svg"
|
||||||
|
color="#96cf05"
|
||||||
|
/>
|
||||||
|
<meta name="apple-mobile-web-app-title" content="NetlifyCMS" />
|
||||||
|
<meta name="application-name" content="NetlifyCMS" />
|
||||||
|
{this.props.headComponents}
|
||||||
|
{css}
|
||||||
|
<link
|
||||||
|
rel="stylesheet"
|
||||||
|
href="https://unpkg.com/docsearch.js@2.5.2/dist/cdn/docsearch.min.css"
|
||||||
|
/>
|
||||||
|
</head>
|
||||||
|
<body {...this.props.bodyAttributes}>
|
||||||
|
{this.props.preBodyComponents}
|
||||||
|
<div
|
||||||
|
key={'body'}
|
||||||
|
id="___gatsby"
|
||||||
|
dangerouslySetInnerHTML={{ __html: this.props.body }}
|
||||||
|
/>
|
||||||
|
{this.props.postBodyComponents}
|
||||||
|
<Gitter room="netlify/NetlifyCMS" />
|
||||||
|
{js}
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
};
|
Before Width: | Height: | Size: 16 KiB |
@ -1,18 +0,0 @@
|
|||||||
{
|
|
||||||
"name": "NetlifyCMS",
|
|
||||||
"icons": [
|
|
||||||
{
|
|
||||||
"src": "/android-chrome-192x192.png",
|
|
||||||
"sizes": "192x192",
|
|
||||||
"type": "image/png"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"src": "/android-chrome-512x512.png",
|
|
||||||
"sizes": "512x512",
|
|
||||||
"type": "image/png"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"theme_color": "#ffffff",
|
|
||||||
"background_color": "#ffffff",
|
|
||||||
"display": "standalone"
|
|
||||||
}
|
|
@ -1,135 +0,0 @@
|
|||||||
// Sticky Nav Functionality in Vanilla JS
|
|
||||||
|
|
||||||
var header = $("#header");
|
|
||||||
|
|
||||||
if ($('.landing.page, .community.page').length) {
|
|
||||||
window.onscroll = function() {
|
|
||||||
|
|
||||||
var currentWindowPos = document.documentElement.scrollTop || document.body.scrollTop;
|
|
||||||
|
|
||||||
if (currentWindowPos > 0) {
|
|
||||||
header.addClass('scrolled');
|
|
||||||
} else {
|
|
||||||
header.removeClass('scrolled');
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
// Auto Indexing Docs Nav
|
|
||||||
|
|
||||||
var indexDocsSubsections = function() {
|
|
||||||
if ($('.docs.page').length) {
|
|
||||||
|
|
||||||
if ($('#docs-content h2').length > 1) {
|
|
||||||
$('<ul class="nav-subsections" id="nav-subsections"></ul>').insertAfter($('#docs-nav .nav-link.active'));
|
|
||||||
|
|
||||||
$('#docs-content h2').each(function() {
|
|
||||||
var sectionTitle = $(this).html(),
|
|
||||||
anchor = $(this).attr("id");
|
|
||||||
|
|
||||||
$('#nav-subsections').append('<li><a class="subnav-link for-' + anchor + '" href="#' + anchor + '">' + sectionTitle + '</a></li>');
|
|
||||||
|
|
||||||
});
|
|
||||||
|
|
||||||
$.localScroll({
|
|
||||||
offset: -120,
|
|
||||||
duration:200,
|
|
||||||
hash:true
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
$(window).on('scroll', function(){
|
|
||||||
window.requestAnimationFrame(scrollHandler);
|
|
||||||
|
|
||||||
function scrollHandler() {
|
|
||||||
var scrollTop = $(window).scrollTop(),
|
|
||||||
windowHeight = $(window).height(),
|
|
||||||
first = false,
|
|
||||||
allSubnavLinks = $("#docs-nav .subnav-link");
|
|
||||||
|
|
||||||
$("#docs-content h2").each( function() {
|
|
||||||
var offset = $(this).offset(),
|
|
||||||
thisLink = '.for-' + $(this).attr("id");
|
|
||||||
|
|
||||||
if (scrollTop <= offset.top && ($(this).height() + offset.top) < (scrollTop + windowHeight) && first == false) {
|
|
||||||
allSubnavLinks.removeClass('active');
|
|
||||||
$(thisLink).addClass('active');
|
|
||||||
first=true;
|
|
||||||
} else {
|
|
||||||
first=false;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
indexDocsSubsections();
|
|
||||||
|
|
||||||
var docsMobileMenu = function() {
|
|
||||||
if ($('.docs.page').length) {
|
|
||||||
|
|
||||||
$("#mobile-docs-nav").change(function() {
|
|
||||||
window.location = $(this).find("option:selected").val();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
docsMobileMenu();
|
|
||||||
|
|
||||||
// search
|
|
||||||
$('#search-button').click(function() {
|
|
||||||
console.log("clicked")
|
|
||||||
$('.search-icon').toggleClass('active');
|
|
||||||
$('.algolia-search').toggleClass('closed');
|
|
||||||
});
|
|
||||||
|
|
||||||
|
|
||||||
// eventbrite info
|
|
||||||
var eventInfoLoad = function() {
|
|
||||||
if ($('.community.page').length) {
|
|
||||||
var eventRequest = new XMLHttpRequest;
|
|
||||||
var eventbriteToken = 'C5PX65CJBVIXWWLNFKLO';
|
|
||||||
var eventbriteOrganiser = '14281996019';
|
|
||||||
eventRequest.open('GET', 'https://www.eventbriteapi.com/v3/events/search/?token=' + eventbriteToken + '&organizer.id=' + eventbriteOrganiser + '&expand=venue%27', true);
|
|
||||||
|
|
||||||
eventRequest.onload = function() {
|
|
||||||
if (eventRequest.status >= 200 && eventRequest.status < 400) {
|
|
||||||
// Success!
|
|
||||||
var data = JSON.parse(eventRequest.responseText);
|
|
||||||
var upcomingDate = data.events[0].start.utc;
|
|
||||||
updateDate(upcomingDate);
|
|
||||||
} else {
|
|
||||||
var upcomingDate = "0000-00-00T00:00:00Z";
|
|
||||||
updateDate(upcomingDate);
|
|
||||||
}
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
eventRequest.onerror = function() {
|
|
||||||
alert('The event info could not be loaded at this time, please try again later.');
|
|
||||||
};
|
|
||||||
|
|
||||||
function updateDate(eventDate) {
|
|
||||||
const eventDateMoment = moment(eventDate);
|
|
||||||
const offset = eventDateMoment.isDST() ? -7 : -8;
|
|
||||||
$('.month').append(eventDateMoment.format('MMMM'));
|
|
||||||
$('.day').append(eventDateMoment.format('DD'));
|
|
||||||
$('.calendar-cta h3 strong:first-child()').append(eventDateMoment.format('dddd, MMMM Do'));
|
|
||||||
$('.calendar-cta h3 strong:last-child()').append(`${eventDateMoment.utcOffset(offset).format('h a')} PT`);
|
|
||||||
}
|
|
||||||
|
|
||||||
eventRequest.send();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
eventInfoLoad();
|
|
||||||
|
|
||||||
|
|
||||||
// Load inline YouTube video
|
|
||||||
var embedcode = '<iframe width="560" height="315" src="https://www.youtube-nocookie.com/embed/p6h-rYSVX90?rel=0&showinfo=0&autoplay=1" frameborder="0" allow="autoplay; encrypted-media" allowfullscreen></iframe>';
|
|
||||||
|
|
||||||
$('.hero-graphic').click(function() {
|
|
||||||
$('.hero-graphic img').replaceWith(embedcode);
|
|
||||||
$('.hero-videolink').remove();
|
|
||||||
});
|
|
66
website/src/layouts/index.js
Normal file
@ -0,0 +1,66 @@
|
|||||||
|
import React, { Fragment } from 'react';
|
||||||
|
import Helmet from 'react-helmet';
|
||||||
|
import classnames from 'classnames';
|
||||||
|
|
||||||
|
import Header from '../components/header';
|
||||||
|
import Footer from '../components/footer';
|
||||||
|
|
||||||
|
import '../css/imports/base.css';
|
||||||
|
import '../css/imports/utilities.css';
|
||||||
|
import '../css/imports/gitter.css';
|
||||||
|
|
||||||
|
const Layout = ({ data, location, children }) => {
|
||||||
|
const { title, description } = data.site.siteMetadata;
|
||||||
|
const notifs = data.notifs.notifications.filter(notif => notif.published);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Fragment>
|
||||||
|
<Helmet defaultTitle={title} titleTemplate={`%s | ${title}`}>
|
||||||
|
<meta name="description" content={description} />
|
||||||
|
</Helmet>
|
||||||
|
{notifs.map((node, i) => (
|
||||||
|
<a
|
||||||
|
key={i}
|
||||||
|
href={node.url}
|
||||||
|
className={classnames('notification', {
|
||||||
|
'notification-loud': node.loud
|
||||||
|
})}
|
||||||
|
>
|
||||||
|
{node.message}
|
||||||
|
</a>
|
||||||
|
))}
|
||||||
|
<Header location={location} notifications={notifs} />
|
||||||
|
{children()}
|
||||||
|
<Footer buttons={data.dataYaml.footer.buttons} />
|
||||||
|
</Fragment>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export const pageQuery = graphql`
|
||||||
|
query layoutQuery {
|
||||||
|
site {
|
||||||
|
siteMetadata {
|
||||||
|
title
|
||||||
|
description
|
||||||
|
}
|
||||||
|
}
|
||||||
|
dataYaml(id: { regex: "/global/" }) {
|
||||||
|
footer {
|
||||||
|
buttons {
|
||||||
|
url
|
||||||
|
name
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
notifs: dataYaml(id: { regex: "/notifications/" }) {
|
||||||
|
notifications {
|
||||||
|
published
|
||||||
|
loud
|
||||||
|
message
|
||||||
|
url
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
|
||||||
|
export default Layout;
|
58
website/src/pages/blog.js
Normal file
@ -0,0 +1,58 @@
|
|||||||
|
import React from 'react';
|
||||||
|
import Helmet from 'react-helmet';
|
||||||
|
import Link from 'gatsby-link';
|
||||||
|
|
||||||
|
const Blog = ({ data }) => (
|
||||||
|
<div className="blog page">
|
||||||
|
<Helmet>
|
||||||
|
<title>Blog</title>
|
||||||
|
<meta
|
||||||
|
name="description"
|
||||||
|
content="Recent news and updates about Netlify CMS."
|
||||||
|
/>
|
||||||
|
</Helmet>
|
||||||
|
<div className="container">
|
||||||
|
<h1>Netlify CMS Blog</h1>
|
||||||
|
{data.allMarkdownRemark.edges.map(({ node }) => (
|
||||||
|
<article className="blog-list-item" key={node.id}>
|
||||||
|
<h2>
|
||||||
|
<Link to={node.fields.slug} className="article">
|
||||||
|
{node.frontmatter.title}
|
||||||
|
</Link>
|
||||||
|
</h2>
|
||||||
|
<p className="meta-info">
|
||||||
|
by {node.frontmatter.author} on {node.frontmatter.date}
|
||||||
|
</p>
|
||||||
|
<p>{node.frontmatter.description}</p>
|
||||||
|
</article>
|
||||||
|
))}
|
||||||
|
{/* TODO: pagination */}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
|
||||||
|
export default Blog;
|
||||||
|
|
||||||
|
export const pageQuery = graphql`
|
||||||
|
query blogList {
|
||||||
|
allMarkdownRemark(
|
||||||
|
filter: { fields: { slug: { regex: "/blog/" } } }
|
||||||
|
sort: { order: DESC, fields: [fields___date] }
|
||||||
|
) {
|
||||||
|
edges {
|
||||||
|
node {
|
||||||
|
id
|
||||||
|
frontmatter {
|
||||||
|
title
|
||||||
|
description
|
||||||
|
author
|
||||||
|
date(formatString: "MMMM D, YYYY")
|
||||||
|
}
|
||||||
|
fields {
|
||||||
|
slug
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`;
|
87
website/src/pages/community.js
Normal file
@ -0,0 +1,87 @@
|
|||||||
|
import React, { Component } from 'react';
|
||||||
|
import Helmet from 'react-helmet';
|
||||||
|
import Markdown from 'react-markdown';
|
||||||
|
|
||||||
|
import EventWidget from '../components/event-widget';
|
||||||
|
import Markdownify from '../components/markdownify';
|
||||||
|
|
||||||
|
import '../css/imports/collab.css';
|
||||||
|
|
||||||
|
const CommunityPage = ({ data }) => {
|
||||||
|
const {
|
||||||
|
title,
|
||||||
|
headline,
|
||||||
|
subhead,
|
||||||
|
primarycta,
|
||||||
|
upcomingevent,
|
||||||
|
howitworks,
|
||||||
|
howtojoin
|
||||||
|
} = data.markdownRemark.frontmatter;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="community page">
|
||||||
|
<Helmet title={title} />
|
||||||
|
<section className="community hero">
|
||||||
|
<div className="contained">
|
||||||
|
<div className="hero-copy">
|
||||||
|
<h1 className="headline">
|
||||||
|
<Markdownify source={headline} />
|
||||||
|
</h1>
|
||||||
|
<h2 className="subhead">
|
||||||
|
<Markdownify source={subhead} />
|
||||||
|
</h2>
|
||||||
|
<h3 className="ctas">
|
||||||
|
<ul>
|
||||||
|
<li>
|
||||||
|
<Markdownify source={primarycta} />
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</h3>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="calendar-cta">
|
||||||
|
<h2>{upcomingevent.hook}</h2>
|
||||||
|
<EventWidget />
|
||||||
|
<div className="cal-cta">
|
||||||
|
<Markdownify source={primarycta} />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section className="how-it-works clearfix">
|
||||||
|
<div className="contained">
|
||||||
|
<div className="half">
|
||||||
|
<h4 className="section-label">How it works</h4>
|
||||||
|
<p>
|
||||||
|
<Markdown source={howitworks} />
|
||||||
|
</p>
|
||||||
|
<h4 className="section-label">How to join</h4>
|
||||||
|
<p>
|
||||||
|
<Markdown source={howtojoin} />
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export const pageQuery = graphql`
|
||||||
|
query communityPage {
|
||||||
|
markdownRemark(id: { regex: "/community/" }) {
|
||||||
|
frontmatter {
|
||||||
|
headline
|
||||||
|
subhead
|
||||||
|
primarycta
|
||||||
|
upcomingevent {
|
||||||
|
hook
|
||||||
|
}
|
||||||
|
howitworks
|
||||||
|
howtojoin
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
|
||||||
|
export default CommunityPage;
|
188
website/src/pages/index.js
Normal file
@ -0,0 +1,188 @@
|
|||||||
|
import React, { Component, Fragment } from 'react';
|
||||||
|
import moment from 'moment';
|
||||||
|
|
||||||
|
import Markdownify from '../components/markdownify';
|
||||||
|
import VideoEmbed from '../components/video-embed';
|
||||||
|
|
||||||
|
import '../css/imports/hero.css';
|
||||||
|
import '../css/imports/cta.css';
|
||||||
|
import '../css/imports/whatsnew.css';
|
||||||
|
import '../css/imports/editors.css';
|
||||||
|
import '../css/imports/community.css';
|
||||||
|
|
||||||
|
const Features = ({ items }) => (
|
||||||
|
<Fragment>
|
||||||
|
{items.map(item => (
|
||||||
|
<div className="feature" key={item.feature}>
|
||||||
|
{item.imgpath && <img src={require(`../img/${item.imgpath}`)} />}
|
||||||
|
<h3>
|
||||||
|
<Markdownify source={item.feature} />
|
||||||
|
</h3>
|
||||||
|
<p>
|
||||||
|
<Markdownify source={item.description} />
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
))}
|
||||||
|
</Fragment>
|
||||||
|
);
|
||||||
|
|
||||||
|
const HomePage = ({ data }) => {
|
||||||
|
const { landing, updates, contribs } = data;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="landing page">
|
||||||
|
<section className="landing hero">
|
||||||
|
<div className="contained">
|
||||||
|
<div className="hero-copy">
|
||||||
|
<h1 className="headline">
|
||||||
|
<Markdownify source={landing.hero.headline} />
|
||||||
|
</h1>
|
||||||
|
<span className="subhead">
|
||||||
|
<Markdownify source={landing.hero.subhead} />
|
||||||
|
</span>
|
||||||
|
<span className="cta-header">
|
||||||
|
<Markdownify source={landing.cta.button} />
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<div className="hero-features">
|
||||||
|
<Features items={landing.hero.devfeatures} />
|
||||||
|
</div>
|
||||||
|
<VideoEmbed />
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section className="cta">
|
||||||
|
<div className="cta-primary">
|
||||||
|
<p>
|
||||||
|
<span className="hook">
|
||||||
|
<Markdownify source={landing.cta.primaryhook} />
|
||||||
|
</span>{' '}
|
||||||
|
<Markdownify source={landing.cta.primary} />
|
||||||
|
</p>
|
||||||
|
<Markdownify source={landing.cta.button} />
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section className="whatsnew">
|
||||||
|
<div className="contained">
|
||||||
|
<ol>
|
||||||
|
{updates.updates.slice(0, 3).map(node => (
|
||||||
|
<a
|
||||||
|
href={`https://github.com/netlify/netlify-cms/releases/tag/${
|
||||||
|
node.version
|
||||||
|
}`}
|
||||||
|
key={node.version}
|
||||||
|
>
|
||||||
|
<li>
|
||||||
|
<div className="update-metadata">
|
||||||
|
<span className="update-version">{node.version}</span>
|
||||||
|
<span className="update-date">
|
||||||
|
{moment(node.date).format('MMMM D, YYYY')}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<span className="update-description">
|
||||||
|
<Markdownify source={node.description} />
|
||||||
|
</span>
|
||||||
|
</li>
|
||||||
|
</a>
|
||||||
|
))}
|
||||||
|
</ol>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section className="editors">
|
||||||
|
<div className="contained">
|
||||||
|
<h2>
|
||||||
|
<Markdownify source={landing.editors.hook} />
|
||||||
|
</h2>
|
||||||
|
<p id="editor-intro">
|
||||||
|
<Markdownify source={landing.editors.intro} />
|
||||||
|
</p>
|
||||||
|
<div className="editors-features">
|
||||||
|
<Features items={landing.editors.features} />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section className="communitysupport">
|
||||||
|
<div className="contained">
|
||||||
|
<h2>
|
||||||
|
<Markdownify source={landing.community.hook} />
|
||||||
|
</h2>
|
||||||
|
<div className="community">
|
||||||
|
<div className="community-features">
|
||||||
|
<Features items={landing.community.features} />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className="contributors feature">
|
||||||
|
<h3>{landing.community.contributors}</h3>
|
||||||
|
<div className="contributor-list">
|
||||||
|
{contribs.contributors.map(user => (
|
||||||
|
<a href={user.profile} title={user.name} key={user.login}>
|
||||||
|
<img
|
||||||
|
src={user.avatar_url.replace('v=4', 's=32')}
|
||||||
|
alt={user.login}
|
||||||
|
/>
|
||||||
|
</a>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export const pageQuery = graphql`
|
||||||
|
query homeQuery {
|
||||||
|
updates: dataYaml(id: { regex: "/updates/" }) {
|
||||||
|
updates {
|
||||||
|
date
|
||||||
|
description
|
||||||
|
version
|
||||||
|
}
|
||||||
|
}
|
||||||
|
landing: dataYaml(id: { regex: "/landing/" }) {
|
||||||
|
hero {
|
||||||
|
headline
|
||||||
|
subhead
|
||||||
|
devfeatures {
|
||||||
|
feature
|
||||||
|
description
|
||||||
|
}
|
||||||
|
}
|
||||||
|
cta {
|
||||||
|
primary
|
||||||
|
primaryhook
|
||||||
|
button
|
||||||
|
}
|
||||||
|
editors {
|
||||||
|
hook
|
||||||
|
intro
|
||||||
|
features {
|
||||||
|
feature
|
||||||
|
imgpath
|
||||||
|
description
|
||||||
|
}
|
||||||
|
}
|
||||||
|
community {
|
||||||
|
hook
|
||||||
|
features {
|
||||||
|
feature
|
||||||
|
description
|
||||||
|
}
|
||||||
|
contributors
|
||||||
|
}
|
||||||
|
}
|
||||||
|
contribs: dataJson(id: { regex: "/contributors/" }) {
|
||||||
|
contributors {
|
||||||
|
name
|
||||||
|
profile
|
||||||
|
avatar_url
|
||||||
|
login
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
|
||||||
|
export default HomePage;
|
46
website/src/templates/blog-post.js
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
import React from 'react';
|
||||||
|
import Helmet from 'react-helmet';
|
||||||
|
|
||||||
|
const BlogPost = ({ data }) => {
|
||||||
|
const { html, frontmatter } = data.markdownRemark;
|
||||||
|
const { author, title, date, description, meta_description } = frontmatter;
|
||||||
|
|
||||||
|
const desc = meta_description || description;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="docs page">
|
||||||
|
<Helmet>
|
||||||
|
<title>{title}</title>
|
||||||
|
{desc && <meta name="description" content={desc} />}
|
||||||
|
</Helmet>
|
||||||
|
<div className="container">
|
||||||
|
<article className="blog-content" id="blog-content">
|
||||||
|
<div className="blog-post-header">
|
||||||
|
<h1>{title}</h1>
|
||||||
|
<p className="meta-info">
|
||||||
|
by {author} on {date}
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<div dangerouslySetInnerHTML={{ __html: html }} />
|
||||||
|
</article>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default BlogPost;
|
||||||
|
|
||||||
|
export const pageQuery = graphql`
|
||||||
|
query blogPost($slug: String!) {
|
||||||
|
markdownRemark(fields: { slug: { eq: $slug } }) {
|
||||||
|
frontmatter {
|
||||||
|
title
|
||||||
|
description
|
||||||
|
# meta_description
|
||||||
|
date(formatString: "MMMM D, YYYY")
|
||||||
|
author
|
||||||
|
}
|
||||||
|
html
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`;
|
108
website/src/templates/doc-page.js
Normal file
@ -0,0 +1,108 @@
|
|||||||
|
import React from 'react';
|
||||||
|
import Helmet from 'react-helmet';
|
||||||
|
import { matchPath } from 'react-router-dom';
|
||||||
|
|
||||||
|
import EditLink from '../components/edit-link';
|
||||||
|
import Widgets from '../components/widgets';
|
||||||
|
import DocsNav from '../components/docs-nav';
|
||||||
|
import MobileNav from '../components/mobile-nav';
|
||||||
|
|
||||||
|
import '../css/lib/prism.css';
|
||||||
|
import '../css/imports/docs.css';
|
||||||
|
|
||||||
|
const toMenu = (menu, nav) =>
|
||||||
|
menu.map(group => ({
|
||||||
|
title: group.title,
|
||||||
|
group: nav.group.find(g => g.fieldValue === group.name)
|
||||||
|
}));
|
||||||
|
|
||||||
|
const DocPage = ({ data, location, history }) => {
|
||||||
|
const { nav, page, widgets, menu } = data;
|
||||||
|
|
||||||
|
const docsNav = toMenu(menu.siteMetadata.menu.docs, nav);
|
||||||
|
const showWidgets = matchPath(location.pathname, { path: '/docs/widgets' });
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="docs detail page">
|
||||||
|
<Helmet title={page.frontmatter.title} />
|
||||||
|
<div className="container">
|
||||||
|
<aside id="sidebar" className="sidebar">
|
||||||
|
<DocsNav items={docsNav} location={location} />
|
||||||
|
<MobileNav items={docsNav} history={history} />
|
||||||
|
</aside>
|
||||||
|
<article className="docs-content" id="docs-content">
|
||||||
|
<EditLink path={page.fields.path} />
|
||||||
|
<h1>{page.frontmatter.title}</h1>
|
||||||
|
<div dangerouslySetInnerHTML={{ __html: page.html }} />
|
||||||
|
{showWidgets && <Widgets widgets={widgets} />}
|
||||||
|
</article>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export const pageQuery = graphql`
|
||||||
|
query docPage($slug: String!) {
|
||||||
|
page: markdownRemark(fields: { slug: { eq: $slug } }) {
|
||||||
|
fields {
|
||||||
|
path
|
||||||
|
}
|
||||||
|
frontmatter {
|
||||||
|
title
|
||||||
|
}
|
||||||
|
html
|
||||||
|
}
|
||||||
|
nav: allMarkdownRemark(
|
||||||
|
sort: { fields: [frontmatter___weight], order: ASC }
|
||||||
|
filter: {
|
||||||
|
frontmatter: { title: { ne: null }, group: { ne: null } }
|
||||||
|
fields: { slug: { regex: "/docs/" } }
|
||||||
|
}
|
||||||
|
) {
|
||||||
|
group(field: frontmatter___group) {
|
||||||
|
fieldValue
|
||||||
|
edges {
|
||||||
|
node {
|
||||||
|
fields {
|
||||||
|
slug
|
||||||
|
}
|
||||||
|
frontmatter {
|
||||||
|
title
|
||||||
|
group
|
||||||
|
}
|
||||||
|
tableOfContents
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
menu: site {
|
||||||
|
siteMetadata {
|
||||||
|
menu {
|
||||||
|
docs {
|
||||||
|
name
|
||||||
|
title
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
widgets: allMarkdownRemark(
|
||||||
|
sort: { fields: [frontmatter___label], order: ASC }
|
||||||
|
filter: {
|
||||||
|
frontmatter: { label: { ne: null } }
|
||||||
|
fields: { slug: { regex: "/widgets/" } }
|
||||||
|
}
|
||||||
|
) {
|
||||||
|
edges {
|
||||||
|
node {
|
||||||
|
frontmatter {
|
||||||
|
label
|
||||||
|
target
|
||||||
|
}
|
||||||
|
html
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
|
||||||
|
export default DocPage;
|
@ -6,17 +6,18 @@ backend:
|
|||||||
|
|
||||||
publish_mode: editorial_workflow
|
publish_mode: editorial_workflow
|
||||||
|
|
||||||
media_folder: "website/site/static/img" # Folder where user uploaded files should go
|
media_folder: "website/static/img" # Folder where user uploaded files should go
|
||||||
public_folder: "img"
|
public_folder: "img"
|
||||||
|
|
||||||
collections: # A list of collections the CMS should be able to edit
|
collections: # A list of collections the CMS should be able to edit
|
||||||
- name: "docs" # Used in routes, ie.: /admin/collections/:slug/edit
|
- name: "docs" # Used in routes, ie.: /admin/collections/:slug/edit
|
||||||
label: "Docs" # Used in the UI, ie.: "New Post"
|
label: "Docs" # Used in the UI, ie.: "New Post"
|
||||||
folder: "website/site/content/docs" # The path to the folder where the documents are stored
|
folder: "website/content/docs" # The path to the folder where the documents are stored
|
||||||
create: true # Allow users to create new documents in this collection
|
create: true # Allow users to create new documents in this collection
|
||||||
fields: # The fields each document in this collection have
|
fields: # The fields each document in this collection have
|
||||||
- {label: "Title", name: "title", widget: "string", tagname: "h1"}
|
- {label: "Title", name: "title", widget: "string", tagname: "h1"}
|
||||||
- {label: "Position", name: "position", widget: "number"}
|
- {label: "Group", name: "group", widget: "string"}
|
||||||
|
- {label: "Weight", name: "weight", widget: "number"}
|
||||||
- {label: "Body", name: "body", widget: "markdown"}
|
- {label: "Body", name: "body", widget: "markdown"}
|
||||||
- name: "blog"
|
- name: "blog"
|
||||||
label: "Blog"
|
label: "Blog"
|
||||||
@ -35,7 +36,7 @@ collections: # A list of collections the CMS should be able to edit
|
|||||||
files:
|
files:
|
||||||
- name: releases
|
- name: releases
|
||||||
label: Releases
|
label: Releases
|
||||||
file: website/site/data/updates.yml
|
file: website/data/updates.yml
|
||||||
fields:
|
fields:
|
||||||
- name: updates
|
- name: updates
|
||||||
label: Releases
|
label: Releases
|
||||||
@ -46,7 +47,7 @@ collections: # A list of collections the CMS should be able to edit
|
|||||||
- {name: description, label: Description}
|
- {name: description, label: Description}
|
||||||
- name: notifications
|
- name: notifications
|
||||||
label: Notifications
|
label: Notifications
|
||||||
file: website/site/data/notifications.yml
|
file: website/data/notifications.yml
|
||||||
description: Site-top notifications - publish one at a time
|
description: Site-top notifications - publish one at a time
|
||||||
fields:
|
fields:
|
||||||
- name: notifications
|
- name: notifications
|
Before Width: | Height: | Size: 356 KiB After Width: | Height: | Size: 356 KiB |
Before Width: | Height: | Size: 5.7 KiB After Width: | Height: | Size: 5.7 KiB |
Before Width: | Height: | Size: 6.1 KiB After Width: | Height: | Size: 6.1 KiB |
@ -2,7 +2,7 @@
|
|||||||
<browserconfig>
|
<browserconfig>
|
||||||
<msapplication>
|
<msapplication>
|
||||||
<tile>
|
<tile>
|
||||||
<square150x150logo src="/mstile-150x150.png"/>
|
<square150x150logo src="mstile-150x150.png"/>
|
||||||
<TileColor>#222222</TileColor>
|
<TileColor>#222222</TileColor>
|
||||||
</tile>
|
</tile>
|
||||||
</msapplication>
|
</msapplication>
|
Before Width: | Height: | Size: 560 B After Width: | Height: | Size: 560 B |