bloke

package module
v0.0.0-...-de016e6 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Oct 7, 2015 License: MIT Imports: 21 Imported by: 0

README

Bloke

Forget about your blog - time for a bloke!
Bloke, you say? Yes, bloke!
  • Bloke (proper noun) - This software!
  • A bloke (noun) - a better kind of blog!
  • To bloke (verb) - a better kind of blogging!

What is this?

Bloke is everything you wanted from a blog and more. With a built in server and AJAX functionality, a bloke gives you blog posts, project pages, and dynamic wiki-bubbles, all generated on the fly from simple markdown files. Use the wiki-bubbles to document important terms, or to build up colossal glossaries. Easily monitor and manage content and contributions with github integration. Connect with millions of internet communities through the Disqus commenting plugin. Bloke's open-source and written in Go (wtih some javascript), so it's fast, easy to install/configure/run, and open to contributions and improvements from anyone!

If you like, Bloke can stand for Bubbles, Love, and Open Knowledge Everywhere. But really it's just a better blog ;)

Install bloke with go get github.com/ebuchman/bloke. To create a new site, use bloke --init site-name, and start adding some content!

Features

  • http server with ajax support for wiki-bubbles
  • automatically generate pages, blog posts, and wiki-bubbles from markdown files
  • serve images and pdfs
  • use subdirectories for pages to create dropdown lists in the navbar
  • convenient testing: automatically detect and serve edits and new files without restarting the server
  • simple production deploy: automatically update on push to github (uses webhooks, requires configuration - see below)
  • manage community edits using github!
  • disqus commenting system connects you with millions of other internet communities worldwide
  • extended markdown for linking to wiki-bubbles
  • meta-info for each post, page, and bubble

How-To

Start a new site with bloke --init site-name. This will create a new root directory with the following directory structure:

site-name/
    config.json
    bubbles/
    imgs/
    files/
    pages/
    posts/

Basics: The pages directory should have a set of markdown files, one for each page of your site (accessible at yoursite/pagename). A link for each page is displayed in the navbar. You can create folders in pages/ and put markdown files in them too - each such folder will give you a dropdown list on the navbar. Blog posts go in the post directory, and must begin with the date in the format yyyy-mm-dd-postname.md. The bubbles directory contains the wiki entries, also as markdown. To create a bubble link (in a page, post, or bubble), use the format [[this text] [some-bubble-entry]] to load the text in some-bubble-entry.md when the this text link is clicked. Finally, place all images in the imgs directory, with the root image named logo.png.

Config: Make sure to edit config.json after creating the site and fill in all fields with the correct information. Most importantly, create a new repo on github and link to it in config.json. Running bloke will initialize a local git repo, make the first commit if it is not already there, and push to the remote. All further git events are on you.

Examples: See an example at https://github.com/ebuchman/ccblog.

Note: it is recommended not to track images and pdfs (or other non markdown files) using git. Use other means to sync such files to your server (ftp, rsync, scp, etc.).

Syncing with GitHub: Webhooks allow autmatic updates to your site simply by pushing changes to the github repo. Using webhooks securely involves generating a secret key and uploading it to github. This must only be done once. To create the secret key for authenticating github webhook requests, cd into the site's directory and run bloke --webhook. This will output a new secret key and save it to a local file .secret. Navigate to https://github.com/your-name/your-site-dir/settings/hooks in your browser and add a new webhook. Set the Payload URL to http://your-bloke-site-domain-name/git/ and paste the secret key just created under Secret. Then press Update webhook. Now, whenever you push to the repo, github will send a post request to your bloke site that will be authenticated via HMAC using the secret key we created. Bloke will then call git pull origin master and update your site. Tada!

Build and Serve: To build and serve the site, cd into the site's root diretory and run bloke --port 8080. Your site is now live on port 8080 (default port without the flag is 9099). Any changes pushed to the github repo will take effect immediately, as with any changes made locally. There is no need to restart the server.

Markdown Refresher

  • italic: *some text*
  • bold: **some text**
  • links: [some text](http://somesite.info)
  • files: [some text](/files/filename.pdf)
  • images: ![img-text](/imgs/img.png)
  • bubbles: [[some text] [wiki-bubble-name]]

URL Rules

  • when linking, only use file extensions for images/files, not for md/html (eg. click [here](/MyProject) for more images like this img-name)
  • all posts and pages are located at /PageName or /yyyy-mm-dd-PostName
  • pages in a subdirectory are specified with their parent: /PageDir/SubPage
  • bubbles are linked simply with their name (no path), eg. [[something cool] [bubble-name]]

Documentation

Index

Constants

This section is empty.

Variables

View Source
var BlokePath = GoPath + "/src/github.com/ebuchman/bloke" // is there a nicer way to get this?
View Source
var GoPath = os.Getenv("GOPATH")

bloke should be launched from the sites root should be installed in gopath/src/github/ebuchman/bloke...

View Source
var NewBubbleString = "This bubble has not been written yet" // this will be changed to refer you to the github repo once it's configured :)

Functions

func BubbleUpdates

func BubbleUpdates(gitpull string) map[string]int

check if changes introduce or change bubbles. return list of them for now it only works on changes, adds, and rms. Rename's mess it all up! redo with regex for christ's sake!

func CheckFatal

func CheckFatal(err error)

func CheckMAC

func CheckMAC(message, messageMAC, key []byte) bool

CheckMAC returns true if messageMAC is a valid HMAC tag for message.

func CreateNewSite

func CreateNewSite(InitSite string)

called on `bloke --init _InitSite`

func CreateSecretToken

func CreateSecretToken()

called on bloke --webhook

func GetTemplates

func GetTemplates(root string) *template.Template

func GetTitleFromMetaInfo

func GetTitleFromMetaInfo(dirPath, name string) string

open a file, parse metainfo, return title fallback to filename if no title

func GetTitleFromUrl

func GetTitleFromUrl(s string) string

get name from url

func IsBloke

func IsBloke(pathname string) bool

check if given dir is a bloke

func IsPost

func IsPost(name string) bool

it's a blog post if it is of the form yyyy-mm-dd-name-of-post.md and the date is quasi valid

func LoadBubble

func LoadBubble(SiteRoot, name string) string

load bubble, parse text, return html string will need an upgrade to json for metainfo...

func ParseBubbles

func ParseBubbles(s []byte) string

parse and replace for bubbles and markdown to js/html takes the raw txt.md bytes creates new bubble entries if they are referenced but don't exist

func ParseFileForNewBubbles

func ParseFileForNewBubbles(pathname string, new_bubbles *map[string]bool)

Find all bubbles, check against old_bubbles, return new bubbles

func ParseForNewBubbles

func ParseForNewBubbles(SiteRoot string) map[string]bool

search every file for new bubbles, create them, return list of new_bubbles

func ReadDir

func ReadDir(dir string) []os.FileInfo

read dir, ignore hidden files/folders

func RedirectServer

func RedirectServer()

func RedirectTLS

func RedirectTLS(w http.ResponseWriter, r *http.Request)

func StartBloke

func StartBloke(addr, SiteRoot string, tls bool, no_html bool)

standalone server for running your own bloke

func StartServer

func StartServer(addr string, mux *http.ServeMux, tls bool)

start a http or https server listening on addr routing with the mux

func WriteSetToFile

func WriteSetToFile(filename string, set map[string]bool)

for writing list of empty bubbles to file

Types

type AjaxBubbleResponseType

type AjaxBubbleResponseType struct {
	Bubbles []Bubble `json:"bubbles"`
}

type Bubble

type Bubble struct {
	Title   string `json:"title"`
	Content string `json:"content"`
}

type ConfigType

type ConfigType struct {
	SiteName string `json:"site_name"`
	Email    string `json:"email"`
	Site     string `json:"site"`
	Repo     string `json:"github_repo"`
	Glossary string `json:"glossary_file"`
	Disqus   string `json:"disqus_user"`
	// contains filtered or unexported fields
}

config struct - corresponds to config.json

type Globals

type Globals struct {
	Projects    [][]string            // list of pairs (url/filename, display name)
	SubProjects map[string][][]string // map from project-filename to list of pairs (subproject filenames, subproject displayname). these generate the dropdowns

	Posts       map[string]map[string]map[string][]string // year, month, day, title
	RecentPosts [][]string                                // [](title, date_name)

	Config   ConfigType // config struct loaded from config.json
	SiteRoot string     // path to the site

	Templates *template.Template

	UpdateHandler UpdateHandler // called with names of updated bubbles
	// contains filtered or unexported fields
}

main site struct

func LiveBloke

func LiveBloke(SitePath string, no_html bool, update_handler UpdateHandler) Globals

launch a new live bloke

func (*Globals) AssemblePages

func (g *Globals) AssemblePages()

compile list of pages and prepare Globals struct (mostly for filling in the nav bar with pages links) in future, write everything out to static .html files for serving later (so we don't have to render template each time)

func (*Globals) AssemblePosts

func (g *Globals) AssemblePosts()

compile list of posts and fill in Globals struct

func (*Globals) AssembleSite

func (g *Globals) AssembleSite()

main server startup function compile lists of pages and posts and prepare globals struct require at least one page and one post!

func (*Globals) ErrorPage

func (g *Globals) ErrorPage(w http.ResponseWriter, err error)

error function

func (*Globals) GitPull

func (g *Globals) GitPull()

if git pull not up to date, refresh Globals how do we pull safely, without messing up a user?!

func (*Globals) IsPage

func (g *Globals) IsPage(name string) bool

it's a page (subpage) if its in blokes list of known pages (subpages)

func (*Globals) LoadConfig

func (g *Globals) LoadConfig(SiteRoot string)

load config struct from config.json

func (*Globals) LoadPage

func (g *Globals) LoadPage(dirPath, name string, page *PageType) error

load and parse a page and relevent metainfo

func (*Globals) LoadSecret

func (g *Globals) LoadSecret()

load webhooks secret from file

func (*Globals) NewServeMux

func (g *Globals) NewServeMux(r Router)

new ServeMux.

func (*Globals) NewWatcher

func (g *Globals) NewWatcher(SiteRoot string)

create new watcher for directory cleanup/close!

func (*Globals) Refresh

func (g *Globals) Refresh(updates map[string]int)

create new globals, copy over (eg. after git pull) takes a list of bubble names recently updates

func (*Globals) RenderTemplate

func (g *Globals) RenderTemplate(w http.ResponseWriter, tmpl string, p interface{})

bring a template to life!

func (*Globals) RenderTemplateToFile

func (g *Globals) RenderTemplateToFile(tmpl, SiteRoot, save_file string, p interface{})

func (*Globals) SaveSite

func (g *Globals) SaveSite()

func (*Globals) ServeBlokeFile

func (g *Globals) ServeBlokeFile(w http.ResponseWriter, r *http.Request)

serve static files (assets: js, css)

func (*Globals) ServeFile

func (g *Globals) ServeFile(w http.ResponseWriter, r *http.Request)

serve static files (imgs, files)

func (*Globals) ServeHTTP

func (g *Globals) ServeHTTP(w http.ResponseWriter, r *http.Request)

serve over the mux

func (*Globals) WatchDirCallback

func (g *Globals) WatchDirCallback(watcher *fsnotify.Watcher)

watch directory callback kind of messy since it fires soo much

func (*Globals) WatchDirs

func (g *Globals) WatchDirs(watcher *fsnotify.Watcher, dir string)

recursive watch all directories

type MetaInfoType

type MetaInfoType struct {
	Title string `json:"title"`
}

meta info struct. read from json

func ParseMetaInfo

func ParseMetaInfo(s []byte) (MetaInfoType, []byte)

parse metainfo. return metainfo struct and remaining bytes

type PageType

type PageType struct {
	Name     string       //URL name of this page
	Text     string       // text of current page
	Title    string       // title of current page
	MetaInfo MetaInfoType // struct of meta info for current page

	// bloke flags (trigger specialized html/templating)
	IsGlossary bool
	IsDisqus   bool
}

info specific to the page requested by a client

type Router

type Router interface {
	ApplyRouting(*http.ServeMux, *Globals)
}

type UpdateHandler

type UpdateHandler interface {
	// takes a list of the names of the updated bubbles
	HandleUpdate(map[string]int)
}

for handling bubble updates this can be ignored, if the updates are in text files being served it can trigger database lookups/modifications it can do whatever else you want point is, separate bloke site generator from the bupble database

type ViewType

type ViewType struct {
	Page    *PageType
	Globals *Globals
}

this guy gets passed to the go templates. simply has pointers to the globals and the page every request sees the same globals, but a different page

Directories

Path Synopsis
cmd

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL