Skip to content

Instantly share code, notes, and snippets.

@xwero
Last active November 25, 2018 01:32
Show Gist options
  • Select an option

  • Save xwero/c82b207008cdc2217539c8923ef20e8e to your computer and use it in GitHub Desktop.

Select an option

Save xwero/c82b207008cdc2217539c8923ef20e8e to your computer and use it in GitHub Desktop.
Sanity static generator POC
export default {
title: 'Column',
name: 'column',
type: 'object',
fieldsets: [
{name: 'content', title: 'Content', description: 'Only add content to one of the options'}
],
fields: [
{
title: 'Name',
name: 'name',
description: 'Backend name',
type: 'string'
},
{
title: 'Identify',
name: 'identify',
description: 'Frontend name',
type: 'string'
},
{
title: 'Layout options',
name: 'layout_options',
description: 'Manipulate content display with classes',
type: 'string'
},
{
title: 'text',
name: 'text',
type: 'array',
of: [{type: 'block'}],
fieldset: 'content'
},
{
title: 'image',
name: 'image',
type: 'image',
fieldset: 'content'
}
],
preview: {
select: {
title: 'name'
}
}
}
export default {
title: "Page",
name: "common_page",
type: "document",
fields: [
{
title: 'Title',
name: 'title',
type: 'string'
},
{
title: 'Path',
name: 'path',
type: 'string'
},
{
title: "Body",
name: "body",
type: "array",
of: [{type: "row"}]
}
]
}
import S from "@sanity/desk-tool/structure-builder";
const hiddenDocTypes = listItem => ![
"homepage"
].includes(listItem.getId())
export default () =>
S.list()
.title("Content")
.items([
S.listItem()
.title("Homepage")
.child(
S.editor()
.id('homepage')
.schemaType("homepage")
.documentId("homepage")
),
...S.documentTypeListItems()
.filter(hiddenDocTypes)
]);
export default {
title: "Homepage",
name: "homepage",
type: "document",
fields: [
{
title: 'Title',
name: 'title',
type: 'string'
},
{
title: "Body",
name: "body",
type: "array",
of: [{type: "row"}]
}
]
}
export default {
title: 'Row',
name: 'row',
type: 'object',
fields: [
{
title: 'Name',
name: 'name',
description: 'Backend name',
type: 'string'
},
{
title: 'Identify',
name: 'identify',
description: 'Frontend name',
type: 'string'
},
{
title: 'Layout options',
name: 'layout_options',
description: 'Manipulate content display with classes',
type: 'string'
},
{
title: 'Column',
name: 'column',
type: 'array',
of: [{type: 'column'}]
}
],
preview: {
select: {
title: 'name'
}
}
}
{
"root": true,
"project": {
"name": "sanity-static-generator"
},
"api": {
"projectId": "add-your-own",
"dataset": "add-your-own"
},
"plugins": [
"@sanity/base",
"@sanity/components",
"@sanity/default-layout",
"@sanity/default-login",
"@sanity/desk-tool",
"@sanity/vision"
],
"parts": [
{
"name": "part:@sanity/base/schema",
"path": "./schemas/schema.js"
},
{
"name": "part:@sanity/desk-tool/structure",
"path": "./deskStructure.js"
}
]
}
// First, we must import the schema creator
import createSchema from 'part:@sanity/base/schema-creator'
// Then import schema types from any plugins that might expose them
import schemaTypes from 'all:part:@sanity/base/schema-type'
import row from './row'
import column from './column'
import homepage from './homepage'
import common_page from './common_page'
// Then we give our schema to the builder and provide the result to Sanity
export default createSchema({
name: 'default',
// Then proceed to concatenate our our document type
// to the ones provided by any plugins that are installed
types: schemaTypes.concat([
row,
column,
homepage,
common_page
])
})
const sanityClient = require('@sanity/client')
const blocksToHtml = require('@sanity/block-content-to-html')
const imageUrlBuilder = require('@sanity/image-url')
const Bitbucket = require('bitbucket')
const FormData = require('form-data')
function buildClasses(object) {
let classes = object.layout_options || ''
if(typeof object.identify !== 'undefined') {
classes += ' ' + object.identify
}
if(classes.length > 0) {
classes = ' ' + classes
}
return classes
}
module.exports = function(context, cb) {
const bitbucket = new Bitbucket()
bitbucket.authenticate({
type: 'basic',
username: context.secrets.bitbucketUser,
password: context.secrets.bitbucketPassword
})
const client = sanityClient({
projectId: context.secrets.sanityProjectId,
dataset: context.secrets.sanityDataset,
token: context.secrets.sanityToken
})
const builder = imageUrlBuilder(client)
const h = blocksToHtml.h
const serializers = {
types: {
code: props => (
h('pre', {className: props.node.language},
h('code', props.node.code)
)
)
}
}
const query = `*[_type in ['homepage', 'common_page']]{
title,
"bodyRows": body[]{
identify,
layout_options,
"columns": column[]{
identify,
layout_options,
text,
image
}
},
path
}`
client
.fetch(query)
.then(pages => {
let formData = new FormData()
pages.forEach(page => {
let pageBuilder = `<!doctype html><title>${page.title}</title><div class="page">`
page.bodyRows.forEach(row => {
const rowClasses = buildClasses(row)
pageBuilder += `<div class="row${rowClasses}">`
row.columns.forEach(column => {
const columnClasses = buildClasses(column)
pageBuilder += `<div class="column${columnClasses}">`
if(typeof column.image !== 'undefined') {
pageBuilder += '<img src="' + builder.image(column.image) + '">'
}else {
pageBuilder += blocksToHtml({
blocks: column.text,
serializers: serializers
})
}
pageBuilder += '</div>'
})
pageBuilder += '</div>'
})
pageBuilder += '</div>'
const filename = typeof page.path !== 'undefined' ? page.path + '.html' : 'index.html'
formData.append(filename, pageBuilder);
})
bitbucket.repositories.createSrcFileCommit({
_body: formData,
repo_slug: context.secrets.bitbucketepo,
username: context.secrets.bitbucketUser
})
.then(({ data, headers }) => {})
.catch((reason) => {
cb(null, {msg: `Handle rejected promise (${reason}) here.`});
})
cb(null, { msg: 'done'});
})
.catch(function(error) {
cb(null, { msg: error});
})
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment