2022-08-05 00:17:26 -04:00
< script lang = "ts" >
2022-08-05 00:57:32 -04:00
import * as EmailValidator from 'email-validator'
2022-08-05 03:28:07 -04:00
import saveAs from 'file-saver'
2022-08-05 00:57:32 -04:00
import Slug from 'slug'
2022-08-26 08:55:30 -04:00
// Meta tags
import { MetaTags } from 'svelte-meta-tags'
2022-08-26 07:28:48 -04:00
// icons
import Icon from 'fa-svelte'
import { faCode } from '@fortawesome/free-solid-svg-icons/faCode'
import { faPaw } from '@fortawesome/free-solid-svg-icons/faPaw'
2022-08-26 08:01:40 -04:00
import { faArrowRight } from '@fortawesome/free-solid-svg-icons/faArrowRight'
2022-08-26 07:28:48 -04:00
2022-08-05 01:26:03 -04:00
export let name: string;
2022-08-05 00:17:26 -04:00
export let email: string;
export let slug: string;
export let bio: string;
2022-08-05 00:57:32 -04:00
let slugIsAuto = true;
2022-08-05 01:24:37 -04:00
let errors = [];
2022-08-05 00:57:32 -04:00
2022-08-05 03:28:07 -04:00
let file: file;
function generateAuthor() {
/*
Generates the author JSON. Note that this
function is very naïve and doesn't perform
any background checks! Please make sure
those have been performed already.
*/
let data = {
data: {
users: [
{
id: 1,
slug: slug,
bio: bio,
email: email,
name: name,
profile_image: ""
},
],
},
meta: {
exported_on: new Date(), // That's today!
version: '2.14.0',
}
}
return JSON.stringify(data)
}
function processForm(e) {
2022-08-05 00:17:26 -04:00
e.preventDefault()
2022-08-05 00:57:32 -04:00
// Check the formatting
2022-08-05 01:24:37 -04:00
errors = []
2022-08-05 00:57:32 -04:00
// First, make sure the required fields are filled
for (let [k,v] of [
['name', name],
['email', email],
['slug', slug]])
{
if (!v) {
errors.push(`${ k } cannot be left blank`)
}
}
// Validate email formatting
2022-08-05 01:26:03 -04:00
if (email && !EmailValidator.validate(email)) {
2022-08-05 00:57:32 -04:00
errors.push(`"${ email } " is not a valid email address`)
}
// Validate slug formatting
2022-08-05 01:24:37 -04:00
if (!errors.length) {
2022-08-05 03:28:07 -04:00
// Generate the file!
file = new File([
generateAuthor()
],
`user-${ slug } .json`,
{
type: 'application/json',
})
// Use FileSaver.js magic to save it
saveAs(file, `user-${ slug } .json`)
console.log(`Name: ${ name } email, ${ email } has slug ${ slug } and bio ${ bio } `)
2022-08-05 00:57:32 -04:00
}
}
function computeSlug() {
/*
Compute the slug from email or name, if it
isn't already computed.
*/
if (!slug || slugIsAuto) {
if (email) {
slug = Slug(email.split('@')[0])
} else if (name) {
slug = Slug(name)
}
}
/*
Of course, if neither email nor name is
set, then we can't do anything about it
*/
}
function updateSlug() {
/*
Marks the slug as manually set (which means
we should stop doing our automatic stuff)
*/
if (slug) {
slugIsAuto = false
// slugify it, just in case
slug = Slug(slug)
} else {
slugIsAuto = true
computeSlug()
}
2022-08-05 00:17:26 -04:00
}
< / script >
2022-08-05 01:23:35 -04:00
< svelte:head >
< title > Ghost User Maker< / title >
2022-08-26 08:55:30 -04:00
< MetaTags title = "Ghost User Maker" description = "A simple tool to generate user JSON files that can be 'imported' to your Ghost website." / >
2022-08-05 01:23:35 -04:00
< / svelte:head >
2022-08-05 00:17:26 -04:00
< main >
2022-08-05 01:26:03 -04:00
< h1 > Ghost User Maker< / h1 >
2022-08-26 08:01:40 -04:00
< p > Enter your new author details below. Once done, click on the "Generate" button to receive a special file that you can import to your < a href = "https://ghost.org" target = "_blank" > Ghost</ a > blog. To do that, go to < i > Settings < span class = "icon" >< Icon class = "icon" icon = { faArrowRight } / ></ span > Labs < span class = "icon" >< Icon icon = { faArrowRight } / ></ span > Import</ i > in your Ghost dashboard, and import the JSON file you downloaded from here. The details will be added to "staff" and you can select them as the author when publishing a post!</ p >
2022-08-05 00:17:26 -04:00
< form >
2022-08-05 01:24:37 -04:00
{ #if errors . length }
< fieldset class = "errors" >
< legend > Errors< / legend >
< ul >
{ #each errors as error }
< li > { error } </ li >
{ /each }
< / ul >
< / fieldset >
{ /if }
2022-08-05 00:17:26 -04:00
< fieldset >
< legend > { name || 'Author' } </ legend >
< div >
< label for = "input-name" > Name< / label >
2022-08-05 00:57:32 -04:00
< input id = "input-name" name = "name" bind:value = { name } on:change= { computeSlug } / >
2022-08-05 00:17:26 -04:00
< / div >
< div >
< label for = "input-email" > Email< / label >
2022-08-05 00:57:32 -04:00
< input id = "input-email" name = "email" type = "email" bind:value = { email } on:change= { computeSlug } / >
2022-08-05 00:17:26 -04:00
< / div >
< div >
< label for = "input-slug" > Slug< / label >
2022-08-05 00:57:32 -04:00
< input id = "input-slug" name = "slug" bind:value = { slug } on:change= { updateSlug } / >
2022-08-05 00:17:26 -04:00
< / div >
< div >
< label for = "input-bio" > Bio< / label >
< input id = "input-bio" name = "bio" bind:value = { bio } / >
< / div >
2022-08-05 03:28:07 -04:00
< button on:click = { processForm } > Generate</button >
2022-08-05 00:17:26 -04:00
< / fieldset >
< / form >
2022-08-26 07:28:48 -04:00
< footer >
2022-08-26 08:01:28 -04:00
< p >< a href = "https://code.snipettemag.com/snipette/ghost-user-maker" target = "_blank" >< span class = "icon" >< Icon icon = { faCode } alt="Built"/ ></ span > with < span class = "icon" >< Icon icon = { faPaw } alt="pawmarks"/ ></ span > by puppies just like you.</ a ></ p >
2022-08-26 07:28:48 -04:00
< / footer >
2022-08-05 00:17:26 -04:00
< / main >
< style >
2022-08-05 01:26:03 -04:00
main {
text-align: center;
padding: 1em;
max-width: none;
margin: 0 auto;
}
2022-08-05 00:17:26 -04:00
fieldset label {
display: inline-block;
}
2022-08-05 01:24:37 -04:00
.errors {
color: red;
border-color: red;
}
2022-08-26 08:01:28 -04:00
.icon {
font-size: 0.8em;
}
2022-08-05 01:24:37 -04:00
fieldset.errors ul {
list-style-type: none;
}
2022-08-05 01:26:03 -04:00
@media (min-width: 640px) {
main {
max-width: 480px;
2022-08-05 00:17:26 -04:00
}
2022-08-05 01:26:03 -04:00
}
2022-08-05 00:17:26 -04:00
< / style >