Use Vue-based templates and NuxtJS framework.
This commit is contained in:
parent
aace761476
commit
90cc334987
1
.gitignore
vendored
1
.gitignore
vendored
@ -1,3 +1,4 @@
|
|||||||
node_modules
|
node_modules
|
||||||
*.spk
|
*.spk
|
||||||
.DS_Store
|
.DS_Store
|
||||||
|
.nuxt
|
||||||
|
@ -3,3 +3,4 @@ set -euo pipefail
|
|||||||
|
|
||||||
cd /opt/app
|
cd /opt/app
|
||||||
yarn install
|
yarn install
|
||||||
|
npm run build
|
||||||
|
@ -1,3 +1,7 @@
|
|||||||
|
# V0.19-sandstorm1
|
||||||
|
|
||||||
|
* Launch screen improvements.
|
||||||
|
|
||||||
# V0.19-sandstorm0 (2017-03-17)
|
# V0.19-sandstorm0 (2017-03-17)
|
||||||
|
|
||||||
* Initial release.
|
* Initial release.
|
||||||
|
File diff suppressed because it is too large
Load Diff
51
app.js
51
app.js
@ -1,51 +0,0 @@
|
|||||||
var express = require("express"),
|
|
||||||
path = require("path"),
|
|
||||||
logger = require("morgan")
|
|
||||||
|
|
||||||
const routes = require("./routes")
|
|
||||||
|
|
||||||
const app = express()
|
|
||||||
|
|
||||||
// view engine setup
|
|
||||||
app.set("views", path.join(__dirname, "views"))
|
|
||||||
app.set("view engine", "jade")
|
|
||||||
|
|
||||||
app.use(logger("dev"))
|
|
||||||
app.use(express.static(path.join(__dirname, "public")))
|
|
||||||
|
|
||||||
app.use('/', routes)
|
|
||||||
|
|
||||||
// catch 404 and forward to error handler
|
|
||||||
app.use((req, res, next) => {
|
|
||||||
const err = new Error("Not Found")
|
|
||||||
err.status = 404
|
|
||||||
next(err)
|
|
||||||
})
|
|
||||||
|
|
||||||
// error handlers
|
|
||||||
|
|
||||||
// development error handler
|
|
||||||
// will print stacktrace
|
|
||||||
if (app.get("env") === 'development') {
|
|
||||||
app.use((err, req, res, next) => {
|
|
||||||
res.status(err.status || 500)
|
|
||||||
res.render("error", {
|
|
||||||
message: err.message,
|
|
||||||
error: err
|
|
||||||
})
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
// production error handler
|
|
||||||
// no stacktraces leaked to user
|
|
||||||
app.use((err, req, res, next) => {
|
|
||||||
res.status(err.status || 500)
|
|
||||||
res.render("error", {
|
|
||||||
message: err.message,
|
|
||||||
error: {}
|
|
||||||
})
|
|
||||||
})
|
|
||||||
|
|
||||||
app.listen(8000, () => console.log("Listening on port 8000"))
|
|
||||||
|
|
||||||
module.exports = app
|
|
61
components/render-template.vue
Normal file
61
components/render-template.vue
Normal file
@ -0,0 +1,61 @@
|
|||||||
|
<template>
|
||||||
|
<iframe ref="iframe" :style="style"/>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
props: {
|
||||||
|
rpcId: {
|
||||||
|
type: String,
|
||||||
|
required: true
|
||||||
|
},
|
||||||
|
template: {
|
||||||
|
type: String,
|
||||||
|
required: true
|
||||||
|
},
|
||||||
|
lines: {
|
||||||
|
type: Number,
|
||||||
|
default() {
|
||||||
|
console.log("template", this.template)
|
||||||
|
if(this.template)
|
||||||
|
return this.template.split("\n").length
|
||||||
|
else
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
},
|
||||||
|
lineHeight: {
|
||||||
|
type: Number,
|
||||||
|
default: 25
|
||||||
|
},
|
||||||
|
style: {
|
||||||
|
type: Object,
|
||||||
|
default() {
|
||||||
|
return {
|
||||||
|
width: "100%",
|
||||||
|
height: (this.lineHeight * this.lines) + "px",
|
||||||
|
border: 0,
|
||||||
|
margin: 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
clipboardButton: {
|
||||||
|
type: String,
|
||||||
|
default: "left"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
mounted() {
|
||||||
|
window.parent.postMessage({renderTemplate: {
|
||||||
|
rpcId: this.rpcId,
|
||||||
|
clipboardButton: this.clipboardButton,
|
||||||
|
template: this.template
|
||||||
|
}}, "*")
|
||||||
|
window.addEventListener("message", (event) => {
|
||||||
|
if(event.data.rpcId == this.rpcId) {
|
||||||
|
if(event.data.error)
|
||||||
|
return this.$emit("error", error)
|
||||||
|
this.$refs.iframe.setAttribute("src", event.data.uri)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
24
layouts/default.vue
Normal file
24
layouts/default.vue
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
<template>
|
||||||
|
<main>
|
||||||
|
<nuxt/>
|
||||||
|
</main>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
body {
|
||||||
|
padding: 50px;
|
||||||
|
font: 14px "Lucida Grande", Helvetica, Arial, sans-serif;
|
||||||
|
}
|
||||||
|
|
||||||
|
a {
|
||||||
|
color: #00B7FF;
|
||||||
|
}
|
||||||
|
|
||||||
|
table {
|
||||||
|
text-align: left;
|
||||||
|
}
|
||||||
|
|
||||||
|
td {
|
||||||
|
padding: 0 10 0 10;
|
||||||
|
}
|
||||||
|
</style>
|
21
nuxt.config.js
Normal file
21
nuxt.config.js
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
module.exports = {
|
||||||
|
/*
|
||||||
|
** Headers of the page
|
||||||
|
*/
|
||||||
|
head: {
|
||||||
|
titleTemplate: "%s - Hugo",
|
||||||
|
meta: [
|
||||||
|
{ charset: 'utf-8' },
|
||||||
|
{ name: 'viewport', content: 'width=device-width, initial-scale=1' }
|
||||||
|
]
|
||||||
|
},
|
||||||
|
/*
|
||||||
|
** Add env variables
|
||||||
|
*/
|
||||||
|
env: {
|
||||||
|
baseURL: process.env.BASE_URL || "http://127.0.0.1:8000"
|
||||||
|
},
|
||||||
|
plugins: [
|
||||||
|
"~plugins/sandstorm"
|
||||||
|
]
|
||||||
|
}
|
16
package.json
16
package.json
@ -1,15 +1,23 @@
|
|||||||
{
|
{
|
||||||
"name": "hugo",
|
"name": "hugo",
|
||||||
"version": "0.0.0",
|
|
||||||
"private": true,
|
"private": true,
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"start": "node ./app"
|
"dev": "nodemon --exec babel-node -w server.js -w nuxt.config.js server.js",
|
||||||
|
"build": "nuxt build",
|
||||||
|
"start": "babel-node server.js"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
"babel-cli": "^6.24.0",
|
||||||
|
"babel-preset-es2015": "^6.24.0",
|
||||||
|
"babel-preset-stage-2": "^6.22.0",
|
||||||
"express": "~4.13.4",
|
"express": "~4.13.4",
|
||||||
"git-http-backend": "^1.0.1",
|
"git-http-backend": "^1.0.1",
|
||||||
"http-proxy": "^1.15.1",
|
"http-proxy": "^1.15.1",
|
||||||
"jade": "~1.11.0",
|
"isomorphic-fetch": "^2.2.1",
|
||||||
"morgan": "~1.7.0"
|
"morgan": "~1.7.0",
|
||||||
|
"nuxt": "^0.9.9"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"nodemon": "^1.11.0"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
95
pages/index.vue
Normal file
95
pages/index.vue
Normal file
@ -0,0 +1,95 @@
|
|||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
<p>Your public site is available at <a :href="url" target="_blank">{{ url }}</a>.</p>
|
||||||
|
<div v-if="!isDemo">
|
||||||
|
<p>To set up your domain to point at your public site, add the following DNS records to your domain. Replace <code>blog.example.com</code> with your site's hostname.</p>
|
||||||
|
<table>
|
||||||
|
<thead>
|
||||||
|
<th>Name</th>
|
||||||
|
<th>Type</th>
|
||||||
|
<th>Value</th>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
<tr>
|
||||||
|
<td>blog.example.com</td>
|
||||||
|
<td>CNAME</td>
|
||||||
|
<td>{{ domain }}</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>sandstorm-www.blog.example.com</td>
|
||||||
|
<td>TXT</td>
|
||||||
|
<td>{{ publicId }}</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
<h2>Editing Your Site</h2>
|
||||||
|
<p>To check out the Git repository containing your site, first add an authorization key to Git:</p>
|
||||||
|
<render-template
|
||||||
|
rpcId="gitAuthorize"
|
||||||
|
:template="'echo url=' + this.gitHost + ' | git -c credential.helper=store credential approve'"/>
|
||||||
|
<p>Then run the following to clone the site:</p>
|
||||||
|
<render-template
|
||||||
|
rpcId="gitClone"
|
||||||
|
:template="'git clone -c credential.helper=store ' + this.gitUrl + ' site'"/>
|
||||||
|
<p>Here are a few pointers to help you get started:</p>
|
||||||
|
<ul>
|
||||||
|
<li>Choose a theme to make your site look nice. Hugo's <a href="https://themes.gohugo.io">theme showcase</a> is a good place to start.</li>
|
||||||
|
<li>Add the theme to your Git repository as a subtree at <code>themes/themename</code>.</li>
|
||||||
|
<li>Add <code>theme = "themename"</code> to <code>Config.toml</code>.</li>
|
||||||
|
<li>Push the repository, and your new site will be immediately published.</li>
|
||||||
|
</ul>
|
||||||
|
<h2>Pushing Existing Site</h2>
|
||||||
|
<p>If you have an existing Hugo site, run the following to publish in this grain:</p>
|
||||||
|
<render-template
|
||||||
|
rpcId="gitPush"
|
||||||
|
:template="'git remote add origin ' + this.gitUrl + '\ngit push -fu origin master'"/>
|
||||||
|
<h2>Admin Interface</h2>
|
||||||
|
<p>Simple site changes can be made directly in the included <a href="/admin/">administrative interface</a>.</p>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import "isomorphic-fetch"
|
||||||
|
import RenderTemplate from "~components/render-template"
|
||||||
|
|
||||||
|
export default {
|
||||||
|
data: () => ({
|
||||||
|
isDemo: true,
|
||||||
|
url: "",
|
||||||
|
domain: "",
|
||||||
|
publicId: ""
|
||||||
|
}),
|
||||||
|
computed: {
|
||||||
|
gitHost: () => {
|
||||||
|
if(process.BROWSER_BUILD)
|
||||||
|
return window.location.protocol+"//git@$API_HOST"
|
||||||
|
else
|
||||||
|
return ""
|
||||||
|
},
|
||||||
|
gitUrl: () => {
|
||||||
|
if(process.BROWSER_BUILD)
|
||||||
|
return `${window.location.protocol}//git@$API_HOST/git`
|
||||||
|
else
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
},
|
||||||
|
mounted() {
|
||||||
|
fetch("/publicId", {
|
||||||
|
credentials: "same-origin"
|
||||||
|
}).then((r) => r.json())
|
||||||
|
.then((r) => {
|
||||||
|
this.isDemo = r.isDemo
|
||||||
|
this.url = r.url
|
||||||
|
this.publicId = r.publicId
|
||||||
|
this.domain = r.domain
|
||||||
|
})
|
||||||
|
.catch(console.error)
|
||||||
|
},
|
||||||
|
head: {
|
||||||
|
title: "Home"
|
||||||
|
},
|
||||||
|
components: {RenderTemplate}
|
||||||
|
}
|
||||||
|
|
||||||
|
</script>
|
7
plugins/sandstorm.js
Normal file
7
plugins/sandstorm.js
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
import router from "~router"
|
||||||
|
|
||||||
|
if(process.BROWSER_BUILD)
|
||||||
|
router.afterEach(() => {
|
||||||
|
window.parent.postMessage({"setTitle": document.title}, "*")
|
||||||
|
window.parent.postMessage({"setPath": location.pathname + location.hash}, "*")
|
||||||
|
})
|
@ -1,16 +0,0 @@
|
|||||||
body {
|
|
||||||
padding: 50px;
|
|
||||||
font: 14px "Lucida Grande", Helvetica, Arial, sans-serif;
|
|
||||||
}
|
|
||||||
|
|
||||||
a {
|
|
||||||
color: #00B7FF;
|
|
||||||
}
|
|
||||||
|
|
||||||
table {
|
|
||||||
text-align: left;
|
|
||||||
}
|
|
||||||
|
|
||||||
td {
|
|
||||||
padding 0 10 0 10;
|
|
||||||
}
|
|
41
routes.js
41
routes.js
@ -1,41 +0,0 @@
|
|||||||
var exec = require("child_process").exec,
|
|
||||||
express = require('express'),
|
|
||||||
httpProxy = require("http-proxy"),
|
|
||||||
router = express.Router(),
|
|
||||||
gitBackend = require("git-http-backend"),
|
|
||||||
spawn = require("child_process").spawn
|
|
||||||
|
|
||||||
router.get('/', (req, res) => {
|
|
||||||
const sessionId = req.headers["x-sandstorm-session-id"]
|
|
||||||
exec(`getPublicId ${sessionId}`, (err, rv) => {
|
|
||||||
if(err)
|
|
||||||
return res.end(err)
|
|
||||||
const lines = rv.split("\n")
|
|
||||||
const publicId = lines[0]
|
|
||||||
const hostname = lines[1]
|
|
||||||
const domain = publicId+"."+hostname
|
|
||||||
const url = lines[2]
|
|
||||||
const isDemo = lines[3] == "true"
|
|
||||||
res.render("index", {domain, isDemo, publicId, url})
|
|
||||||
})
|
|
||||||
})
|
|
||||||
|
|
||||||
router.use("/git", (req, res) => {
|
|
||||||
req.pipe(gitBackend(req.url, (err, service) => {
|
|
||||||
if(err)
|
|
||||||
return res.end(err+"\n")
|
|
||||||
res.setHeader("content-type", service.type)
|
|
||||||
console.log("cmd", service.cmd)
|
|
||||||
const ps = spawn(service.cmd, service.args.concat("/var/git"))
|
|
||||||
ps.stdout.pipe(service.createStream()).pipe(ps.stdin)
|
|
||||||
})).pipe(res)
|
|
||||||
})
|
|
||||||
|
|
||||||
var proxy = httpProxy.createProxyServer({
|
|
||||||
target: "http://127.0.0.1:8001/admin/",
|
|
||||||
changeOrigin: true
|
|
||||||
})
|
|
||||||
|
|
||||||
router.use("/admin/", (req, res) => proxy.web(req, res))
|
|
||||||
|
|
||||||
module.exports = router
|
|
68
server.js
Normal file
68
server.js
Normal file
@ -0,0 +1,68 @@
|
|||||||
|
import Nuxt from "nuxt"
|
||||||
|
import logger from "morgan"
|
||||||
|
const exec = require("child_process").exec
|
||||||
|
import Express from "express"
|
||||||
|
import gitBackend from "git-http-backend"
|
||||||
|
import httpProxy from "http-proxy"
|
||||||
|
const spawn = require("child_process").spawn
|
||||||
|
|
||||||
|
const app = new Express()
|
||||||
|
|
||||||
|
app.use(logger("dev"))
|
||||||
|
const server = require("http").createServer(app)
|
||||||
|
const host = process.env.HOST || "127.0.0.1"
|
||||||
|
const port = process.env.PORT || "8000"
|
||||||
|
|
||||||
|
app.set("port", port)
|
||||||
|
|
||||||
|
app.get("/publicId", (req, res) => {
|
||||||
|
const sessionId = req.headers["x-sandstorm-session-id"]
|
||||||
|
exec(`getPublicId ${sessionId}`, (err, rv) => {
|
||||||
|
if(err)
|
||||||
|
return res.end(err)
|
||||||
|
const lines = rv.split("\n")
|
||||||
|
const publicId = lines[0]
|
||||||
|
const hostname = lines[1]
|
||||||
|
const domain = publicId+"."+hostname
|
||||||
|
const url = lines[2]
|
||||||
|
const isDemo = lines[3] == "true"
|
||||||
|
res.json({publicId, hostname, domain, url, isDemo})
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
app.use("/git", (req, res) => {
|
||||||
|
req.pipe(gitBackend(req.url, (err, service) => {
|
||||||
|
if(err)
|
||||||
|
return res.end(err+"\n")
|
||||||
|
res.setHeader("content-type", service.type)
|
||||||
|
console.log("cmd", service.cmd)
|
||||||
|
const ps = spawn(service.cmd, service.args.concat("/var/git"))
|
||||||
|
ps.stdout.pipe(service.createStream()).pipe(ps.stdin)
|
||||||
|
})).pipe(res)
|
||||||
|
})
|
||||||
|
|
||||||
|
const proxy = httpProxy.createProxyServer({
|
||||||
|
target: "http://127.0.0.1:8001/admin/",
|
||||||
|
changeOrigin: true
|
||||||
|
})
|
||||||
|
|
||||||
|
app.use("/admin/", (req, res) => proxy.web(req, res))
|
||||||
|
|
||||||
|
// Import and Set Nuxt.js options
|
||||||
|
let config = require("./nuxt.config.js")
|
||||||
|
config.dev = !(process.env.NODE_ENV === "production")
|
||||||
|
|
||||||
|
// Init Nuxt.js
|
||||||
|
const nuxt = new Nuxt(config)
|
||||||
|
app.use(nuxt.render)
|
||||||
|
|
||||||
|
// Build only in dev mode
|
||||||
|
if (config.dev) {
|
||||||
|
nuxt.build()
|
||||||
|
.catch((error) => {
|
||||||
|
console.error(error) // eslint-disable-line no-console
|
||||||
|
process.exit(1)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
server.listen(port, host, () => console.log(`Server listening on ${host}:${port}`))
|
@ -1,6 +0,0 @@
|
|||||||
extends layout
|
|
||||||
|
|
||||||
block content
|
|
||||||
h1= message
|
|
||||||
h2= error.status
|
|
||||||
pre #{error.stack}
|
|
@ -1,69 +0,0 @@
|
|||||||
extends layout
|
|
||||||
|
|
||||||
block content
|
|
||||||
h1 Hugo
|
|
||||||
p
|
|
||||||
| Your public site is available at:
|
|
||||||
a(href = url target = "_blank")= url
|
|
||||||
| .
|
|
||||||
- if(!isDemo)
|
|
||||||
p To set up your domain to point at your public site, add the following DNS records to your domain. Replace <code>blog.example.com</code> with your site's hostname.
|
|
||||||
table
|
|
||||||
thead
|
|
||||||
th Name
|
|
||||||
th Type
|
|
||||||
th Value
|
|
||||||
tbody
|
|
||||||
tr
|
|
||||||
td blog.example.com
|
|
||||||
td CNAME
|
|
||||||
td= domain
|
|
||||||
tr
|
|
||||||
td sandstorm-www.blog.example.com
|
|
||||||
td TXT
|
|
||||||
td= publicId
|
|
||||||
h2 Editing your site
|
|
||||||
p To check out the Git repository containing your site, first add an authorization key to Git:
|
|
||||||
iframe#gitAuthorize(style = "width: 100%; height: 25px; margin: 0; border: 0;")
|
|
||||||
p Then run the following to clone the site:
|
|
||||||
iframe#gitClone(style = "width: 100%; height: 25px; margin: 0; border: 0;")
|
|
||||||
p Here are a few pointers to help you get started:
|
|
||||||
li
|
|
||||||
| Choose a theme to make your site look nice. Hugo’s
|
|
||||||
a(href = "https://themes.gohugo.io/") theme showcase
|
|
||||||
| is a good place to start.
|
|
||||||
li Add the theme to your Git repository as a subtree at <code>themes/themename</code>.
|
|
||||||
li Add <code>theme = "themename"</code> to <code>Config.toml</code>.
|
|
||||||
li Push the repository, and your new site will be immediately published.
|
|
||||||
h2 Pushing existing site
|
|
||||||
p If you have an existing Hugo site, run the following to publish in this grain:
|
|
||||||
iframe#gitPush(style = "width: 100%; height: 50px; margin: 0; border: 0;")
|
|
||||||
h2 Admin interface
|
|
||||||
p
|
|
||||||
| You can do simple changes to your site directly in the
|
|
||||||
a(href = "/admin/") admin interface
|
|
||||||
| .
|
|
||||||
|
|
||||||
script.
|
|
||||||
document.addEventListener("DOMContentLoaded", function() {
|
|
||||||
window.parent.postMessage({renderTemplate: {
|
|
||||||
rpcId: "gitAuthorize",
|
|
||||||
template: "echo url=" + window.location.protocol + "//git:$API_TOKEN@$API_HOST | git -c credential.helper=store credential approve"
|
|
||||||
}}, "*")
|
|
||||||
window.parent.postMessage({renderTemplate: {
|
|
||||||
rpcId: "gitClone",
|
|
||||||
template: "git clone -c credential.helper=store " + window.location.protocol + "//git@$API_HOST/git site"
|
|
||||||
}}, "*")
|
|
||||||
window.parent.postMessage({renderTemplate: {
|
|
||||||
rpcId: "gitPush",
|
|
||||||
template: "git remote add origin " + window.location.protocol + "//git@$API_HOST/git\ngit push -fu origin master"
|
|
||||||
}}, "*")
|
|
||||||
})
|
|
||||||
window.addEventListener("message", function(event) {
|
|
||||||
if(event.data.error)
|
|
||||||
console.log(error)
|
|
||||||
else {
|
|
||||||
var el = document.getElementById(event.data.rpcId)
|
|
||||||
el.setAttribute("src", event.data.uri)
|
|
||||||
}
|
|
||||||
})
|
|
@ -1,6 +0,0 @@
|
|||||||
doctype html
|
|
||||||
html
|
|
||||||
head
|
|
||||||
link(rel='stylesheet', href='/stylesheets/style.css')
|
|
||||||
body
|
|
||||||
block content
|
|
Loading…
Reference in New Issue
Block a user