diff --git a/.gitignore b/.gitignore index 77a34bc..2a76665 100644 --- a/.gitignore +++ b/.gitignore @@ -7,12 +7,14 @@ pom.xml.asc /target/ /checkouts/ /resources/public/content/.git +/resources/public/vendor .lein-deps-sum .lein-repl-history .lein-plugins/ .lein-failures .lein-env - - +.nrepl-port +smeagol.log* /node_modules/ -/resources/public/vendor/ +.DS_Store + diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..0dfae96 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,3 @@ +FROM tomcat:alpine +COPY target/smeagol-*-standalone.war $CATALINA_HOME/webapps/smeagol.war + diff --git a/README.md b/README.md index c809a8a..03cd9d1 100644 --- a/README.md +++ b/README.md @@ -1,69 +1,162 @@ -![One wiki to rule them all](https://www.weft.scot/images/smeagol.png) - -# Welcome to Smeagol! -Smeagol is a simple Wiki engine inspired by [Gollum](https://github.com/gollum/gollum/wiki). Gollum is a Wiki engine written in Ruby, which uses a number of simple text formats including [Markdown](http://daringfireball.net/projects/markdown/), and which uses [Git](http://git-scm.com/) to provide versioning and backup. I needed a new Wiki for a project and thought Gollum would be ideal - but unfortunately it doesn't provide user authentication, which I needed, and it was simpler for me to reimplement the bits I did need in Clojure than to modify Gollum. - -So at this stage Smeagol is a Wiki engine written in Clojure which uses Markdown as its text format, which does have user authentication, and which uses Git as its versioning and backup system. - -## Status -Smeagol is now a fully working small Wiki engine, and meets my own immediate needs. - -## Markup syntax -Smeagol uses the Markdown format as provided by [markdown-clj](https://github.com/yogthos/markdown-clj), with the addition that anything enclosed in double square brackets, \[\[like this\]\], will be treated as a link into the wiki itself. - -## Security and authentication -Security is now greatly improved. There is a file called *passwd* in the *resources* directory, which contains a clojure map which maps usernames to maps with plain-text passwords and emails thus: - - {:admin {:password "admin" :email "admin@localhost" :admin true} - :adam {:password "secret" :email "adam@localhost"}} - -that is to say, the username is a keyword and the corresponding password is a string. However, since version 0.5.0, users can now change their own passwords, and when the user changes their password their new password is encrypted using the [scrypt](http://www.tarsnap.com/scrypt.html) one-way encryption scheme. The password file is now no longer either in the *resources/public* directory so cannot be downloaded through the browser, nor in the git archive to which the Wiki content is stored, so that even if that git archive is remotely clonable an attacker cannot get the password file that way. - -## Images -Smeagol does not currently have any mechanism to upload images. You can, however, link to images already available on the web, like this: - -![Smeagol](http://vignette3.wikia.nocookie.net/lotr/images/e/e1/Gollum_Render.png/revision/latest?cb=20141218075509) - -## Todo -* Mechanism to add users through the user interface; - -## Advertisement -If you like what you see here, I am available for work on open source Clojure projects. Contact me vis [WEFT](http://www.weft.scot/). - -### Phoning home -Smeagol currently requests the WEFT logo in the page footer from my home site. This is mainly so I can get a feel for how many people are using the product. If you object to this, edit the file - - resources/templates/base.html - -and replace the line - - Developed by WEFT - -with the line - - Developed by WEFT - -## License -Copyright © 2014-2015 Simon Brooke. Licensed under the GNU General Public License, -version 2.0 or (at your option) any later version. If you wish to incorporate -parts of Smeagol into another open source project which uses a less restrictive -license, please contact me; I'm open to dual licensing it. - -## Prerequisites -You will need [Leiningen](https://github.com/technomancy/leiningen) 2.0 or above installed. - -You will need [node](https://nodejs.org/en/) and [bower](https://bower.io/) installed. - -## Running -To start a web server for the application, run: - - lein bower install - lein ring server - -Alternatively, if you want to deploy to a servlet container (which I would strongly recommend), the simplest thing is to run: - - lein bower install - lein ring uberwar - -(a command which I'm sure Smeagol would entirely appreciate) and deploy the resulting war file. - +![One wiki to rule them all](https://www.weft.scot/images/smeagol.png) + +# Welcome to Smeagol! +Smeagol is a simple Wiki engine inspired by [Gollum](https://github.com/gollum/gollum/wiki). Gollum is a Wiki engine written in Ruby, which uses a number of simple text formats including [Markdown](http://daringfireball.net/projects/markdown/), and which uses [Git](http://git-scm.com/) to provide versioning and backup. I needed a new Wiki for a project and thought Gollum would be ideal - but unfortunately it doesn't provide user authentication, which I needed, and it was simpler for me to reimplement the bits I did need in Clojure than to modify Gollum. + +So at this stage Smeagol is a Wiki engine written in Clojure which uses Markdown as its text format, which does have user authentication, and which uses Git as its versioning and backup system. + + + +## Status +Smeagol is now a fully working small Wiki engine, and meets my own immediate needs. + +## Markup syntax +Smeagol uses the Markdown format as provided by [markdown-clj](https://github.com/yogthos/markdown-clj), with the addition that anything enclosed in double square brackets, \[\[like this\]\], will be treated as a link into the wiki itself. + +### Pluggable extensible markup + +A system of pluggable, extensible formatters is supported. In normal markdown, code blocks may be delimited by three backticks at start and end, and often the syntax of the code can be indicated by a token immediately following the opening three backticks. This has been extended to allow custom formatters to be provided for such code blocks. Two example formatters are provided: + +#### The Vega formatter + +Inspired by [visdown](http://visdown.amitkaps.com/) and [vega-lite](https://vega.github.io/vega-lite/docs/), the Vega formatter allows you to embed vega data visualisations into Smeagol pages. The graph description should start with a line comprising three back-ticks and then the word '`vega`', and end with a line comprising just three backticks. + +Here's an example cribbed in its entirety from [here](http://visdown.amitkaps.com/london): + +##### Flight punctuality at London airports + +```vega +data: + url: "data/london.csv" +transform: + - + filter: datum.year == 2016 +mark: rect +encoding: + x: + type: nominal + field: source + y: + type: nominal + field: dest + color: + type: quantitative + field: flights + aggregate: sum +``` + +Data files can be uploaded in the same way as images, by using the **upload a file** link. + +Note that this visualisation will not be rendered in the GitHub wiki, as it doesn't have Smeagol's data visualisation magic. This is what it should look like: + +![Example visualisation](https://github.com/simon-brooke/smeagol/blob/develop/resources/public/data/london.png?raw=true) + +#### The Mermaid formatter + +Graphs can now be embedded in a page using the [Mermaid](http://knsv.github.io/mermaid/index.html) graph description language. The graph description should start with a line comprising three back-ticks and then the word `mermaid`, and end with a line comprising just three backticks. + +Here's an example culled from the Mermaid documentation. + +##### GANTT Chart + +```mermaid +gantt + dateFormat YYYY-MM-DD + title Adding GANTT diagram functionality to mermaid + section A section + Completed task :done, des1, 2014-01-06,2014-01-08 + Active task :active, des2, 2014-01-09, 3d + Future task : des3, after des2, 5d + Future task2 : des4, after des3, 5d + section Critical tasks + Completed task in the critical line :crit, done, 2014-01-06,24h + Implement parser and jison :crit, done, after des1, 2d + Create tests for parser :crit, active, 3d + Future task in critical line :crit, 5d + Create tests for renderer :2d + Add to mermaid :1d +``` + +To add your own formatter, compile it into a jar file which is on the classpath - it does *not* have to be part of the Smeagol project directly, and then edit the value of the key `:formatters` in the file `config.edn`; whose standard definition is: + + :formatters {"vega" smeagol.formatting/process-vega + "vis" smeagol.formatting/process-vega + "mermaid" smeagol.formatting/process-mermaid} + +The added key should be the word which will follow the opening three backticks of your code block, and the value of that key should be a symbol which evaluates to a function which can format the code block as required. + +## Security and authentication +Security is now greatly improved. There is a file called *passwd* in the *resources* directory, which contains a clojure map which maps usernames to maps with plain-text passwords and emails thus: + + {:admin {:password "admin" :email "admin@localhost" :admin true} + :adam {:password "secret" :email "adam@localhost"}} + +that is to say, the username is a keyword and the corresponding password is a string. However, since version 0.5.0, users can now change their own passwords, and when the user changes their password their new password is encrypted using the [scrypt](http://www.tarsnap.com/scrypt.html) one-way encryption scheme. The password file is now no longer either in the *resources/public* directory so cannot be downloaded through the browser, nor in the git archive to which the Wiki content is stored, so that even if that git archive is remotely clonable an attacker cannot get the password file that way. + +## Images +You can (if you're logged in) upload files, including images, using the **Upload a file** link on the top menu bar. You can link to an uploaded image, or other images already available on the web, like this: + +![Smeagol](http://vignette3.wikia.nocookie.net/lotr/images/e/e1/Gollum_Render.png/revision/latest?cb=20141218075509) + +## Advertisement +If you like what you see here, I am available for work on open source Clojure projects. + +### Phoning home +Smeagol currently requests the WEFT logo in the page footer from my home site. This is mainly so I can get a feel for how many people are using the product. If you object to this, edit the file + + resources/templates/base.html + +and replace the line + + Developed by WEFT + +with the line + + Developed by WEFT + +## License +Copyright © 2014-2015 Simon Brooke. Licensed under the GNU General Public License, +version 2.0 or (at your option) any later version. If you wish to incorporate +parts of Smeagol into another open source project which uses a less restrictive +license, please contact me; I'm open to dual licensing it. + +## Prerequisites +You will need [Leiningen](https://github.com/technomancy/leiningen) 2.0 or above installed. + +You will need [node](https://nodejs.org/en/) and [bower](https://bower.io/) installed. + +## Running +To start a web server for the application, run: + + lein bower install + lein ring server + +Alternatively, if you want to deploy to a servlet container (which I would strongly recommend), the simplest thing is to run: + + lein bower install + lein ring uberwar + +(a command which I'm sure Smeagol would entirely appreciate) and deploy the resulting war file. + +## Experimental Docker image + +You can now run Smeagol as a [Docker](http://www.docker.com) image. To run my Docker image, use + + docker run simonbrooke/smeagol + +Smeagol will run, obviously, on the IP address of your Docker image, on port 8080. To find the IP address, start the image using the command above and then use + + docker inspect --format '{{ .NetworkSettings.IPAddress }}' $(docker ps -q) + +Suppose this prints '10.10.10.10', then the URL to browse to will be http://10.10.10.10:8080/smeagol/ + +This image is _experimental_, but it does seem to work fairly well. What it does **not** yet do, however, is push the git repository to a remote location, so when you tear the Docker image down your edits will be lost. My next objective for this image is for it to have a cammand line parameter being the git address of a repository from which it can initialise the Wiki content, and to which it will periodically push local changes to the Wiki content. + +To build your own Docker image, run: + + lein clean + lein bower install + lein ring uberwar + lein docker build + +This will build a new Docker image locally; you can, obviously, push it to your own Docker repository if you wish. diff --git a/project.clj b/project.clj index 40eeea6..eb2ad78 100644 --- a/project.clj +++ b/project.clj @@ -1,54 +1,86 @@ -(defproject smeagol "0.5.0-rc3" +(defproject smeagol "1.0.0-rc3" :description "A simple Git-backed Wiki inspired by Gollum" :url "https://github.com/simon-brooke/smeagol" - :dependencies [[org.clojure/clojure "1.7.0"] - [org.clojure/core.memoize "0.5.9"] - [com.taoensso/encore "2.91.1"] - [lib-noir "0.9.9" :exclusions [org.clojure/tools.reader]] + :license {:name "GNU General Public License,version 2.0 or (at your option) any later version" + :url "https://www.gnu.org/licenses/old-licenses/gpl-2.0.en.html"} + :dependencies [[clj-jgit "0.8.10"] + [clj-yaml "0.4.0"] + [com.cemerick/url "0.1.1"] + [com.fzakaria/slf4j-timbre "0.3.7"] + [com.taoensso/encore "2.92.0"] [com.cemerick/url "0.1.1"] - [ring-server "0.4.0"] - [selmer "1.10.9"] - - [org.clojure/tools.logging "0.4.0"] [com.taoensso/timbre "4.10.0"] [com.fzakaria/slf4j-timbre "0.3.7"] - [org.slf4j/slf4j-api "1.7.25"] - [org.slf4j/log4j-over-slf4j "1.7.25"] - [org.slf4j/jul-to-slf4j "1.7.25"] - [org.slf4j/jcl-over-slf4j "1.7.25"] - [com.taoensso/tower "3.0.2" :exclusions [com.taoensso/encore]] - [markdown-clj "0.9.99" :exclusions [com.keminglabs/cljx]] [crypto-password "0.2.0"] - [clj-jgit "0.8.9"] [environ "1.1.0"] + [hiccup "1.0.5"] [im.chit/cronj "1.4.4"] + [lib-noir "0.9.9" :exclusions [org.clojure/tools.reader]] + [markdown-clj "0.9.99" :exclusions [com.keminglabs/cljx]] [noir-exception "0.2.5"] - [prone "1.1.4"]] + [org.clojars.simon_brooke/internationalisation "1.0.3"] + [org.clojure/clojure "1.8.0"] + [org.clojure/core.memoize "0.5.9"] + [org.clojure/data.json "0.2.6"] + [org.clojure/tools.logging "0.4.0"] + [org.slf4j/slf4j-api "1.7.25"] + [org.slf4j/log4j-over-slf4j "1.7.25"] + [org.slf4j/jul-to-slf4j "1.7.25"] + [org.slf4j/jcl-over-slf4j "1.7.25"] + [prone "1.1.4"] + [ring/ring-anti-forgery "1.1.0"] + [ring-server "0.4.0"] + [selmer "1.11.0"]] :repl-options {:init-ns smeagol.repl} + :jvm-opts ["-server"] - :plugins [[lein-ring "0.8.13" :exclusions [org.clojure/clojure]] - [lein-environ "1.0.0"] + + :plugins [[lein-ancient "0.5.5" :exclusions [org.clojure/clojure org.clojure/data.xml]] [lein-bower "0.5.1"] - [lein-ancient "0.5.5" :exclusions [org.clojure/clojure org.clojure/data.xml]] - [lein-marginalia "0.7.1" :exclusions [org.clojure/clojure]]] - :bower-dependencies [[simplemde "1.11.2"]] + [lein-codox "0.10.3"] + [io.sarnowski/lein-docker "1.0.0"] + [lein-environ "1.0.0"] + [lein-marginalia "0.7.1" :exclusions [org.clojure/clojure]] + [lein-ring "0.8.13" :exclusions [org.clojure/clojure]]] + + :bower-dependencies [[simplemde "1.11.2"] + ;; [vega-embed "3.0.0-beta.20"] ;; vega-embed currently not loaded from Bower because of + ;; dependency conflict which will hopefully be resolved soon. + [vega-lite "2.0.0-beta.11"] + [mermaid "6.0.0"]] + + :docker {:image-name "simonbrooke/smeagol" + :dockerfile "Dockerfile"} + :ring {:handler smeagol.handler/app :init smeagol.handler/init :destroy smeagol.handler/destroy} - :lein-release {:scm :git :deploy-via :lein-install} - :profiles - {:uberjar {:omit-source true - :env {:production true} - :aot :all} - :production {:ring {:open-browser? false - :stacktraces? false - :auto-reload? false}} - :dev {:dependencies [[ring-mock "0.1.5"] - [ring/ring-devel "1.6.2"] - [pjstadig/humane-test-output "0.8.2"]] - :injections [(require 'pjstadig.humane-test-output) - (pjstadig.humane-test-output/activate!)] - :env {:dev true}}} + + :release-tasks [["vcs" "assert-committed"] + ["change" "version" "leiningen.release/bump-version" "release"] + ["vcs" "commit"] + ;; ["vcs" "tag"] -- not working, problems with secret key + ["clean"] + ["bower" "install"] + ["ring" "uberwar"] + ["docker" "build"] + ["docker" "push"] + ["change" "version" "leiningen.release/bump-version"] + ["vcs" "commit"]] + + :profiles {:uberjar {:omit-source true + :env {:production true} + :aot :all} + :production {:ring {:open-browser? false + :stacktraces? false + :auto-reload? false}} + :dev {:dependencies [[ring-mock "0.1.5"] + [ring/ring-devel "1.6.2"] + [pjstadig/humane-test-output "0.8.2"]] + :injections [(require 'pjstadig.humane-test-output) + (pjstadig.humane-test-output/activate!)] + :env {:dev true}}} + :min-lein-version "2.0.0") diff --git a/resources/config.edn b/resources/config.edn new file mode 100644 index 0000000..27c6a8b --- /dev/null +++ b/resources/config.edn @@ -0,0 +1,35 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;; +;;;; Smeagol: a very simple Wiki engine. +;;;; +;;;; This program is free software; you can redistribute it and/or +;;;; modify it under the terms of the GNU General Public License +;;;; as published by the Free Software Foundation; either version 2 +;;;; of the License, or (at your option) any later version. +;;;; +;;;; This program is distributed in the hope that it will be useful, +;;;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;;;; GNU General Public License for more details. +;;;; +;;;; You should have received a copy of the GNU General Public License +;;;; along with this program; if not, write to the Free Software +;;;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, +;;;; USA. +;;;; +;;;; Copyright (C) 2017 Simon Brooke +;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +;;; config.edn: a simple configuration map for Smeagol; inspired by Cryogen. +;;; This is top-level configuration. + +;; ; ; ; ; ; ; ; ; ; +{ + :site-title "Smeagol" ;; overall title of the site, used in page headings + :default-locale "en-GB" ;; default language used for messages + :formatters {"vega" smeagol.formatting/process-vega + "vis" smeagol.formatting/process-vega + "mermaid" smeagol.formatting/process-mermaid + "backticks" smeagol.formatting/process-backticks} +} diff --git a/resources/i18n/en-GB.edn b/resources/i18n/en-GB.edn new file mode 100644 index 0000000..a7b8789 --- /dev/null +++ b/resources/i18n/en-GB.edn @@ -0,0 +1,143 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;; +;;;; Smeagol: a very simple Wiki engine. +;;;; +;;;; This program is free software; you can redistribute it and/or +;;;; modify it under the terms of the GNU General Public License +;;;; as published by the Free Software Foundation; either version 2 +;;;; of the License, or (at your option) any later version. +;;;; +;;;; This program is distributed in the hope that it will be useful, +;;;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;;;; GNU General Public License for more details. +;;;; +;;;; You should have received a copy of the GNU General Public License +;;;; along with this program; if not, write to the Free Software +;;;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, +;;;; USA. +;;;; +;;;; Copyright (C) 2017 Simon Brooke +;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +;;; en-GB.edn: English-language messages. +;;; This is essentially all the text in the chrome - that which isn't editable +;;; through the wiki itself; and the test in the sanity check report. + +;; ; ; ; ; ; ; ; ; ; +{:add-user-label "Add new user" ;; label for the add user link on edit users page + :change-pass-label "Change password!" + ;; text of the change password widget itself on the + ;; change password page + :change-pass-link "Change password" + ;; text of the change password link on the menu + :change-pass-prompt "To change your password" + ;; text of the change password widget prompt on the + ;; change password page + :change-col-hdr "Changes" ;; header for the changes column in history + :chpass-bad-match "Your proposed passwords don't match" + ;; error text if proposed passwords don't match + :chpass-fail "Your password was not changed" + ;; error text on fail other htan too short or bad match + :chpass-success "Your password was changed" + ;; confirmation text on password change + :chpass-too-short "You proposed password wasn't long enough: eight characters required" + ;; error text if proposed password is too short + :chpass-title-prefix "Change password for" + ;; prefix for title of change password page + :content-dir "The content directory" + ;; used in sanity check report + :content-dir-exists "The content directory exists" + ;; used in sanity check report + :content-dir-is-dir "The content directory is a directory" + ;; used in sanity check report + :cookies-about "About cookies" ;; about cookies text + :cookies-more "This website stores session information as a 'cookie' on your browser. This helps us show you the content you want to see. This cookie does not identify you, and cannot be read by other websites. It is deleted by your browser as soon as you leave this site. This website does not use any third party cookies, so your visit here cannot be tracked by other websites." + ;; more about cookies text + :default-page-title "Introduction" ;; title of the default page in this wiki + :del-col-hdr "Delete" ;; header for delete column on edit users page + :del-user-fail "Could not delete user" + ;; error message on failure to delete user + :del-user-success "Successfully deleted user" + ;; confirmation message on deletion of user + :diff-title-prefix "Changes since version" + ;; prefix for the header of the changes page + :does-not-exist "does not exist" + ;; (of a file or directory); used in sanity check report + :edit-col-hdr "Edit" ;; header for edit column on edit users page + :edit-page-link "Edit this page" + ;; text of the edit page link on the content frame + :edit-title-prefix "Edit" ;; prefix for title of edit content page + :edit-users-link "Edit users" ;; text of the edit users link on the menu + :edit-users-title "Select user to edit" + ;; title of edit users page + :email-prompt "Email address" ;; text of the email widget prompt on edit user page + :file-or-directory "File or directory" + ;; used in sanity check report + :file-summary-prompt "Description/what's changed" + ;; prompt for the file upload summary input + :file-upload-link-text "You may link to this file using a link of the form" + ;; Text introducing the link to an uploaded file + :file-upload-prompt "File to upload" ;; prompt string for the file upload widget + :file-upload-title "Upload a file" ;; title for the file upload page + :is-admin-prompt "Is administrator?" + :here "here" ;; used in sanity check report + :home-link "Home" ;; text of the home link on the menu + :is-not-directory "is not a directory" + ;; (of a file or directory) used in sanity check report + :is-not-readable "is not readable" + ;; (of a file or directory) used in sanity check report + :is-not-writable "is not writable" + ;; (of a file or directory) used in sanity check report + :login-label "Log in!" ;; text of the login widget on the login page + :login-link "Log in" ;; text of the login link on the menu + :login-prompt "To edit this wiki" + ;; text of the action widget prompt on the login page + :logout-label "Log out!" ;; text of the logout widget on the logout page + :logout-link "Log out" ;; text of the logout link on the menu + :logged-in-as "You are logged in as" + ;; text of the 'logged in as' label on the menu + :history-link "History" ;; text of the history link on the content frame + :history-title-prefix "History of" ;; prefix of the title on the history page + :new-pass-prompt "New password" ;; text of the new password widget prompt on the change + ;; password and edit user pages + :no-admin-users "There are no users in the 'passwd' file with administrative privileges" + ;; used in sanity check report + :old-pass-prompt "Your password" + ;; text of the old password widget prompt on the change + ;; password page, and password widget on login page + :password-file "the password ('passwd') file" + ;; used in sanity check report + :problems-found "problems were found" + ;; used in sanity check report + :rpt-pass-prompt "And again" ;; text of the new password widget prompt on the change + ;; password and edit user pages + :save-prompt "When you have finished editing" + ;; text of the save widget label on edit content + ;; and edit user page + :save-label "Save!" ;; text of the save widget itself + :save-user-fail "Failed to store user" + :save-user-success "Successfully stored user" + :see-documentation "For more information please see documentation " + ;; used in sanity check report + :smeagol-not-initialised + "Smeagol is not initialised correctly" + ;; title of the sanity check report + :smeagol-misconfiguration + "Smeagol has been unable to find some of the resources on which it depends, + possibly because of misconfiguration or missing environment variables." + ;; used in sanity check report + :user-lacks-field "User record in the passwd file lacks a field" + ;; used in sanity check report + :username-prompt "Username" ;; text of the username widget prompt on edit user page + ;; text of the is admin widget prompt on edit user page + :user-title-prefix "Edit user" ;; prefix for title of edit user page + :vers-col-hdr "Version" ;; header for the version column in history + :what-col-hdr "What" ;; header for the what column in history + :what-changed-prompt "What have you changed?" + ;; text of the summary widget prompt on edit + ;; content page + :when-col-hdr "When" ;; header for the when column in history + :your-uname-prompt "Your username" ;; text of the username widget prompt on the login page + } diff --git a/resources/i18n/en.edn b/resources/i18n/en.edn new file mode 120000 index 0000000..bc94dc4 --- /dev/null +++ b/resources/i18n/en.edn @@ -0,0 +1 @@ +en-GB.edn \ No newline at end of file diff --git a/resources/passwd b/resources/passwd index 3744ac1..6b5e6ac 100644 --- a/resources/passwd +++ b/resources/passwd @@ -1 +1 @@ -{:admin {:admin true, :email "info@weft.scot", :password "admin"}} \ No newline at end of file +{:admin {:admin true, :email "info@weft.scot", :password "admin"}, :jenny {:email "jenny@auchencairn.org", :admin false, :password "$s0$f0801$1uniQfftB37G5e5GklJANQ==$kQ0+/YcCuaz2x5iYjwhNlDlnWX/exE/8pSC+R4C0WvQ="}} \ No newline at end of file diff --git a/resources/public/content/Configuration.md b/resources/public/content/Configuration.md new file mode 100644 index 0000000..fd29caf --- /dev/null +++ b/resources/public/content/Configuration.md @@ -0,0 +1,20 @@ +Smeagol reads a configuration file, whose content should be formatted as a clojure map. + +The default content is as follows: + + { + :site-title "Smeagol" ;; overall title of the site, used in page headings + :default-locale "en-GB" ;; default language used for messages + :formatters {"vega" smeagol.formatting/process-vega + "vis" smeagol.formatting/process-vega + "mermaid" smeagol.formatting/process-mermaid + "backticks" smeagol.formatting/process-backticks} + } + +The three keys given above should be present. The values should be: + +* **:site-title** The title for your wiki +* **:default-locale** A string comprising a lower-case [ISO 639](https://en.wikipedia.org/wiki/ISO_639) code specifying a language, optionally followed by a hyphen and an upper-case [ISO 3166](https://en.wikipedia.org/wiki/ISO_3166) specifying a country. +* **:formatters** A map of formatters used in [[Extensible Markup]], q.v. + +The default file is at `resources/config.edn`; this default can be overridden by providing an environment variable, `SMEAGOL_CONFIG`, whose value is the full or relative pathname of a suitable file. diff --git a/resources/public/content/Deploying Smeagol.md b/resources/public/content/Deploying Smeagol.md new file mode 100644 index 0000000..653831a --- /dev/null +++ b/resources/public/content/Deploying Smeagol.md @@ -0,0 +1,60 @@ +## Deploying as a stand-alone application +To deploy Smeagol as a stand-alone application, either download the jar file for the release you want to deploy, or clone the source and compile it with: + + lein bower install + lein ring uberjar + +This will create a jar file in the `target` directory, named `smeagol-`*VERSION*`-standalone.jar`. + +Smeagol cannot access either its configuration or its content from the jar file, as otherwise they would not be editable. Consequently you should set up three environment variables: + +1. `SMEAGOL_CONFIG` should be the full or relative pathname of a Smeagol [[Configuration]] file; +2. `SMEAGOL_CONTENT_DIR` should be the full or relative pathname of the directory from which Smeagol should serve content (which may initially be empty, but must be writable by the process which runs Smeagol)' +3. `SMEAGOL_PASSWD` should be the full or relative pathname of a Smeagol Passwd file - see [[Security and authentication]]. This file must contain an entry for at least your initial user, and, if you want to administer users through the user interface, must be writable by the process which runs Smeagol. + +**NOTE** that `SMEAGOL_CONTENT_DIR` must contain at least the following files: + +1. `_edit-side-bar.md` - the side-bar that should be displayed when editing pages; +2. `_header.md` - the header to be displayed on all pages; +3. `_side-bar.md` - the side-bar that should be displayed when not editing pages. + +Standard versions of these files can be found in the [source repository](https://github.com/journeyman-cc/smeagol/tree/master/resources/public/content). All these files should be in markdown format - see [[Extensible Markup]]. + +You can run the jar file with: + + java -jar smeagol-VERSION-standalone.jar + +## Deploying within a servlet container +To deploy Smeagol within a servlet container, either download the jar file for the release you want to deploy, or clone the source and compile it with: + + lein bower install + lein ring uberwar + +This will create a war file in the `target` directory, named `smeagol-`*VERSION*`-standalone.war`. Deploy this to your servlet container in the normal way; details will depend on your container. Instructions for Tomcat are [here](https://tomcat.apache.org/tomcat-8.0-doc/deployer-howto.html). + +The problem with this is that unless the environment variables (see above) were already set up in the environment of the servlet container at the time when the servlet container were launched, Smeagol will run with its built-in defaults. This will run perfectly satisfactorily provided your servlet container is configured to unpack war files, which most are. + +## Experimental Docker image + +You can now run Smeagol as a [Docker](http://www.docker.com) image. Read more about [[Using the Docker Image]]. + +To run my Docker image, use + + docker run simonbrooke/smeagol + +Smeagol will run, obviously, on the IP address of your Docker image, on port 8080. To find the IP address, start the image using the command above and then use + + docker inspect --format '{{ .NetworkSettings.IPAddress }}' $(docker ps -q) + +Suppose this prints '10.10.10.10', then the URL to browse to will be http://10.10.10.10:8080/smeagol/ + +This image is _experimental_, but it does seem to work fairly well. What it does **not** yet do, however, is push the git repository to a remote location, so when you tear the Docker image down your edits will be lost. My next objective for this image is for it to have a cammand line parameter being the git address of a repository from which it can initialise the Wiki content, and to which it will periodically push local changes to the Wiki content. + +To build your own Docker image, run: + + lein clean + lein bower install + lein ring uberwar + lein docker build + +This will build a new Docker image locally; you can, obviously, push it to your own Docker repository if you wish. diff --git a/resources/public/content/Developing Smeagol.md b/resources/public/content/Developing Smeagol.md new file mode 100644 index 0000000..79f40d5 --- /dev/null +++ b/resources/public/content/Developing Smeagol.md @@ -0,0 +1,24 @@ +## Prerequisites + +You will need [Leiningen](https://github.com/technomancy/leiningen) 2.0 or above installed. + +You will need [node](https://nodejs.org/en/) and [bower](https://bower.io/) installed. + +## Running in development +To start a web server for the application during development, run: + + lein bower install + lein ring server + +This should start a development server, and open a new window or tab in your default browser with the default page of the wiki loaded into it. + +## Editing +I generally use [LightTable](http://lighttable.com/) as my `Clojure` editor, but it doesn't really matter what you use; if you run Smeagol as described above, then all changes you make in the code (and save) will instantly be applied to the running system. This makes for a productive development environment. + +## Documentation +It is my intention that the code should be sufficiently well documented to be easy to understand. Documentation may be generated from the code by running + + lein codox + +## Contributing +If you make changes to Smeagol which you think are useful, please contribute them in the form of a [pull request on github](https://help.github.com/articles/creating-a-pull-request/). diff --git a/resources/public/content/Extensible Markup.md b/resources/public/content/Extensible Markup.md new file mode 100644 index 0000000..e0b1fed --- /dev/null +++ b/resources/public/content/Extensible Markup.md @@ -0,0 +1,101 @@ +The basic format of Smeagol pages is [Markdown](https://daringfireball.net/projects/markdown/); documentation on how to format them is [here](https://daringfireball.net/projects/markdown/syntax). Note that there are a number of slightly different variants of Markdown; the version used by Smeagol does not currently allow tables. + +A system of pluggable, extensible formatters is supported. In normal markdown, code blocks may be delimited by three backticks at start and end, and often the syntax of the code can be indicated by a token immediately following the opening three backticks. This has been extended to allow custom formatters to be provided for such code blocks. Two example formatters are provided: + +## The Vega formatter + +Inspired by [visdown](http://visdown.amitkaps.com/) and [vega-lite](https://vega.github.io/vega-lite/docs/), the Vega formatter allows you to embed vega data visualisations into Smeagol pages. The graph description should start with a line comprising three back-ticks and then the word '`vega`', and end with a line comprising just three backticks. + +Here's an example cribbed in its entirety from [here](http://visdown.amitkaps.com/london): + +### Flight punctuality at London airports + +```vega +data: + url: "data/london.csv" +transform: + - + filter: datum.year == 2016 +mark: rect +encoding: + x: + type: nominal + field: source + y: + type: nominal + field: dest + color: + type: quantitative + field: flights + aggregate: sum +``` + +Data files can be uploaded in the same way as images, by using the **upload a file** link. + +## The Mermaid formatter + +Graphs can now be embedded in a page using the [Mermaid](http://knsv.github.io/mermaid/index.html) graph description language. The graph description should start with a line comprising three back-ticks and then the word `mermaid`, and end with a line comprising just three backticks. + +Here's an example culled from the Mermaid documentation. + +### GANTT Chart + +```mermaid +gantt + dateFormat YYYY-MM-DD + title Adding GANTT diagram functionality to mermaid + section A section + Completed task :done, des1, 2014-01-06,2014-01-08 + Active task :active, des2, 2014-01-09, 3d + Future task : des3, after des2, 5d + Future task2 : des4, after des3, 5d + section Critical tasks + Completed task in the critical line :crit, done, 2014-01-06,24h + Implement parser and jison :crit, done, after des1, 2d + Create tests for parser :crit, active, 3d + Future task in critical line :crit, 5d + Create tests for renderer :2d + Add to mermaid :1d +``` + +## Writing your own custom formatters + +A custom formatter is simply a Clojure function which takes a string and an integer as arguments and produces a string as output. The string is the text the user has typed into their markdown; the integer is simply a number you can use to keep track of which addition to the page this is, in order, for example, to fix up some JavaScript to render it. + +For example, here's the formatter which handles the Vega charts: + + (defn process-vega + "Process this `vega-src` string, assumed to be in YAML format, into a specification + of a Vega chart, and add the plumbing to render it." + [^String vega-src ^Integer index] + (str + "
\n" + "")) + +### Configuring Smeagol to use your formatter + +To add your own formatter, compile it into a jar file which is on the classpath - it does *not* have to be part of the Smeagol project directly - and then edit the value of the key `:formatters` in the file `config.edn`; whose standard definition is: + + :formatters {"vega" smeagol.formatting/process-vega + "vis" smeagol.formatting/process-vega + "mermaid" smeagol.formatting/process-mermaid} + +The added key should be the word which will follow the opening three backticks of your code block, and the value of that key should be a symbol which evaluates to the function you have written. So suppose your formatter was called `my-magic-formatter`; you'd written it in a namespace called `magic.core`; and you wanted users to identify it with the word `magic`, you'd add the following to the `:formatters` map: + + "magic" magic.core/my-magic-formatter + +Users could then put a section in their markdown text: + +```backticks magic + wingardium leviosa +``` + +and your function would be called with "wingardium leviosa" as the first argument. diff --git a/resources/public/content/Introduction.md b/resources/public/content/Introduction.md index ae4b565..6709957 100644 --- a/resources/public/content/Introduction.md +++ b/resources/public/content/Introduction.md @@ -1,71 +1,41 @@ +![One wiki to rule them all](https://www.weft.scot/images/smeagol.png) + # Welcome to Smeagol! Smeagol is a simple Wiki engine inspired by [Gollum](https://github.com/gollum/gollum/wiki). Gollum is a Wiki engine written in Ruby, which uses a number of simple text formats including [Markdown](http://daringfireball.net/projects/markdown/), and which uses [Git](http://git-scm.com/) to provide versioning and backup. I needed a new Wiki for a project and thought Gollum would be ideal - but unfortunately it doesn't provide user authentication, which I needed, and it was simpler for me to reimplement the bits I did need in Clojure than to modify Gollum. So at this stage Smeagol is a Wiki engine written in Clojure which uses Markdown as its text format, which does have user authentication, and which uses Git as its versioning and backup system. ## Status -Smeagol is now a fully working small Wiki engine, and meets my own immediate needs. There are some obvious -things which could be improved - see **TODO** list below - but it works now and doesn't seem to have any major problems. +Smeagol is now a fully working small Wiki engine, and meets my own immediate needs. + +## Using Smeagol +Read the [[User Documentation]] for an introduction to all Smeagol's features. ## Markup syntax -Smeagol uses the Markdown format as provided by [markdown-clj](https://github.com/yogthos/markdown-clj), with the addition that anything enclosed in double square brackets, \[\[like this\]\], will be treated as a link into the wiki itself. Here's an example [[Internal Link]]. +Smeagol uses the Markdown format as provided by [markdown-clj](https://github.com/yogthos/markdown-clj), with the addition that anything enclosed in double square brackets, \[\[like this\]\], will be treated as a link into the wiki itself. Read more about [[Extensible Markup]]. ## Security and authentication -Security is now greatly improved. There is a file called *passwd* in the *resources* directory, which contains a clojure map which maps usernames to maps with plain-text passwords and emails thus: - - {:admin {:password "admin" :email "admin@localhost" :admin true} - :adam {:password "secret" :email "adam@localhost"}} - -that is to say, the username is a keyword and the corresponding password is a string. However, since version 0.5.0, users can now change their own passwords, and when the user changes their password their new password is encrypted using the [scrypt](http://www.tarsnap.com/scrypt.html) one-way encryption scheme. The password file is now no longer either in the *resources/public* directory so cannot be downloaded through the browser, nor in the git archive to which the Wiki content is stored, so that even if that git archive is remotely clonable an attacker cannot get the password file that way. +Smeagol now has good security and authentication. While the initial password supplied with the system is not encrypted, when it is changed it will be; and passwords for new users added through the user administration pages are encrypted. Read more about [[Security and authentication]]. ## Images -Smeagol does not currently have any mechanism to upload images. You can, however, link to images already available on the web, like this: +You can (if you're logged in) upload files, including images, using the **Upload a file** link on the top menu bar. You can link to an uploaded image, or to other images already available on the web, like this: ![Smeagol](http://vignette3.wikia.nocookie.net/lotr/images/e/e1/Gollum_Render.png/revision/latest?cb=20141218075509) -## Todo -* Mechanism to add users through the user interface; - -## Advertisement -If you like what you see here, I am available for work on open source Clojure projects. Contact me vis [WEFT](http://www.weft.scot/). - -### Phoning home -Smeagol currently requests the WEFT logo in the page footer from my home site. This is mainly so I can get a feel for how many people are using the product. If you object to this, edit the file - - resources/templates/base.html - -and replace the line - - Developed by WEFT +## Running Smeagol +You can run Smeagol from the [[Docker Image]]; alternatively you can run it from an executable jar file or as a war file in a servlet container. Read how in [[Deploying Smeagol]]. -with the line - - Developed by WEFT +## Developing Smeagol +Smeagol is an open source project; you're entitled to make changes yourself. Read more about [[Developing Smeagol]]. ## License -Copyright © 2014-2015 Simon Brooke. Licensed under the GNU General Public License, +Copyright © 2014-2017 Simon Brooke. Licensed under the GNU General Public License, version 2.0 or (at your option) any later version. If you wish to incorporate parts of Smeagol into another open source project which uses a less restrictive license, please contact me; I'm open to dual licensing it. -## Prerequisites -You will need [Leiningen](https://github.com/technomancy/leiningen) 2.0 or above installed. - -You will need [node](https://nodejs.org/en/) and [bower](https://bower.io/) installed. - -## Running -To start a web server for the application, run: - - lein bower install - lein ring server - -Alternatively, if you want to deploy to a servlet container (which I would strongly recommend), the simplest thing is to run: +## Phoning home +Smeagol does currently fetch one image from my home site. Read more about [[Phoning Home]], and how to prevent it (if you want to). - lein bower install - lein ring uberwar - -(a command which I'm sure Smeagol would entirely appreciate) and deploy the resulting war file. - - -## Editing the framing content -You can edit the [stylesheet](/edit-css?page=stylesheet), the [[\_left-bar]], the [[\_edit-left-bar]], and the [[\_header]]. +## Advertisement +If you like what you see here, I am available for work on open source Clojure projects. diff --git a/resources/public/content/Phoning Home.md b/resources/public/content/Phoning Home.md new file mode 100644 index 0000000..48c4019 --- /dev/null +++ b/resources/public/content/Phoning Home.md @@ -0,0 +1,11 @@ +Smeagol currently requests the WEFT logo in the page footer from my home site. This is mainly so I can get a feel for how many people are using the product. If you object to this, edit the file + + resources/templates/base.html + +and replace the line + + Developed by WEFT + +with the line + + Developed by WEFT diff --git a/resources/public/content/Security and authentication.md b/resources/public/content/Security and authentication.md new file mode 100644 index 0000000..9bc5b00 --- /dev/null +++ b/resources/public/content/Security and authentication.md @@ -0,0 +1,18 @@ +Security is now greatly improved over earlier releases of Smeagol. There is a file called `passwd` which by default is in the `resources` directory, which contains a [`Clojure` map](https://clojure.org/reference/data_structures#Maps) which maps usernames to maps with plain-text passwords and emails thus: + + {:admin {:password "admin" :email "admin@localhost" :admin true} + :adam {:password "secret" :email "adam@localhost"}} + +that is to say, the username is a keyword and the corresponding password is a string. However, since version 0.5.0, users can now change their own passwords, and when the user changes their password their new password is encrypted using the [scrypt](http://www.tarsnap.com/scrypt.html) one-way encryption scheme. The password file is now no longer either in the `resources/public` directory so cannot be downloaded through the browser, nor in the git archive to which the Wiki content is stored, so that even if that git archive is remotely clonable an attacker cannot get the password file that way. + +## Fields in the user record +Keys and their associated values in the individual user's record are as follows: + +* `:password` The user's password, which can be plain text (if set via the user interface, an encrypted password is stored) +* `:email` The user's email address (not currently used; may be used in future for sending password reset messages) +* `:admin` If present and set to `true`, the user has access to the user administration functions. + +## Maintaining the passwd file outside the Smeagol deployment +You may set an environment variable, `SMEAGOL_PASSWD`, to indicate a `passwd` file anywhere you like on the file system provided the process running Smeagol can read it; but unless the file is writable by the process which Smeagol runs as you will not be able to administer users through the user interface. + +Of course, it is possible to edit the file using a text editor and maintain the list of allowed users in that way. \ No newline at end of file diff --git a/resources/public/content/User Documentation.md b/resources/public/content/User Documentation.md new file mode 100644 index 0000000..92435ff --- /dev/null +++ b/resources/public/content/User Documentation.md @@ -0,0 +1,124 @@ +## If you're using a small device +If you're using a small device, like a mobile phone, the top menu isn't usually displayed. Instead there will be an image like this: +![Menu icon](/img/three-lines.png) + +at the top left of the page. Touching this image will cause the top menu to be displayed, and it will have all the options described in this documentation. + +## Logging in +If you are not logged in, there will be an option `Log in` on the top menu. Note that if you're not an English language speaker, the menu items may be in your own language (provided we have a suitable language file). You must log in to edit pages, to change your password, or to perform administration. + +Selecting the 'Log in' option will take you to the log in page. This will prompt you for your username and password. If you have just set up a new instance of Smeagol, your username will be `admin` and your password will be `admin`. **Note** It is very important to change this default password after logging in. + + +-------------------------------------------------------------------------+ + | +----------------------------------+ | + | Your username: | | | + | +----------------------------------+ | + | Your password: | | | + | +----------------------------------+ | + | +-----------+ | + | To edit this wiki | Log in! | | + | +-----------+ | + +-------------------------------------------------------------------------+ + +Once you have entered your username and password, select the green `Log in!` button, or press `return` on your keyboard. + +### Changing your password +To change your password, select the `Change password` option from the top menu. This will take you to the `Change password for...` page. This will prompt you for your (old) password, and your new password, twice. Complete the form and select the green `Change password!` button, or hit return. + + +-------------------------------------------------------------------------+ + | +----------------------------------+ | + | Your password: | | | + | +----------------------------------+ | + | New password: | | | + | +----------------------------------+ | + | And again: | | | + | +----------------------------------+ | + | +--------------------+ | + | To change your password | Change password! | | + | +--------------------+ | + +-------------------------------------------------------------------------+ + +If there is a problem (for example, the password wasn't long enough, or your new passwords didn't match), a message will show in red below the header of the page to explain the problem. Complete the form again. + +If the form was submitted successfully and your password is changed, a message will be shown in green below the header of the page confirming this. + +## Viewing page history +You can view the edit history of any page in the Wiki. At the top right of the content area, you will find a link `History`. Selecting this will take you to a page listing all the edits that have been made. Each row shows you: + +* When the change was made +* What was changed (and who changed it) + +It also provides a link `Show Version`, and a link `What's changed since?` + +### Viewing a specific version +Selecting the `Show Version` link from any version in the page history will open the version of the page exactly as it was immediately after that edit. Selecting the `What's changed since?` link will show a page which highlights all the changes made to the page since that edit, with added text shown in green and deleted text in red. + +## Editing pages +If you are logged in you can edit any page in the Wiki. At the top right of the content area, you will find a link `Edit this page`. Selecting this opens the page in the editor. + +The editor is not strictly 'what you see is what you get', but it's fairly close to it. Icons on the ribbon above the content area allow you to apply simple styling. There are some prompts in the sidebar which will help with more complicate things. + +### Markup syntax +Smeagol uses the Markdown format as provided by [markdown-clj](https://github.com/yogthos/markdown-clj), with the addition that anything enclosed in double square brackets, \[\[like this\]\], will be treated as a link into the wiki itself. Smeagol also supports [[Extensible Markup]]. + +## Uploading files +To upload a file (including an image file), select the link `Upload a file` from the top menu. **Warning:** do not do this while you are editing a page, or you will lose your edit! + +Selecting the link will take you to the `Upload a file` page. This will prompt you for the file you wish to upload. Select your file, and then select the green `Save!` button. + +After your file has uploaded, you will be shown a link which can be copied and pasted into a Wiki page to link to that file. + +You must be logged in to upload files. + +## Administering users + +If you are an administrator, you can administer the users who are entitled to edit and administer the Wiki. When you are logged in, there will be a a link `Edit users` on the top menu. Selecting this will take you to the `Edit users` page which lists users, with an `Edit...` and a `Delete...` link for each. Below the existing users will be a link `Add new user`. + +### Editing a user + +Selecting the `Edit...` link for any user from the `Edit users` page, or the `Add new user` link from the same page, will take you to the `Edit user` form. + +This page has the following inputs: + + +-------------------------------------------------------------------------+ + | +----------------------------------+ | + | Username: | | | + | +----------------------------------+ | + | New password: | | | + | +----------------------------------+ | + | And again: | | | + | +----------------------------------+ | + | Email address: | | | + | +----------------------------------+ | + | Is Administrator? [ ] | + | +---------+ | + | When you have finished editing | Save! | | + | +---------+ | + +-------------------------------------------------------------------------+ + +#### To add a new user + +When using this form after selecting the `Add new user` link, all fields will be blank. Complete at least the fields `Username`, `New password`, `And again`, and `Email address`. If the new user is to be an administrator, check the box labelled `Is Administrator`. Finally, select the green button marked `Save!`. Your new user will be saved. + +#### To edit an existing user + +When using this form after selecting the `Edit...` link against a particular user, the `Username` field will already be filled in (and you won't be able to edit it). The `Email address` field will also probably be filled in. If the user is an administrator, the `Is Administrator` box will be checked. The `New password` and `And again` fields will be blank. You may alter the email address or change the `Is Administrator` status. + +#### To change the password of an existing user + +Smeagol does not have a mechanism to allow users to reset their own password if they have forgotten it. Instead, they will have to ask an administrator to do this. + +On the `Edit user` page for the existing user, enter their new password in the fields `New password` and `And again`; then select the green button marked `Save!`. **Warning** If you do not want to change the password, leave these fields blank! + +## To log out + +When you've finished editing the Wiki, you should log out. Select the `Log out` link from the top menu. This will take you to a very simple form: + + +-------------------------------------------------------------------------+ + | +------------+ | + | When you have finished editing | Log out! | | + | +------------+ | + +-------------------------------------------------------------------------+ + +Select the red `Log out!` button to log out. + diff --git a/resources/public/content/_header.md b/resources/public/content/_header.md index d50260c..161c6f7 100644 --- a/resources/public/content/_header.md +++ b/resources/public/content/_header.md @@ -1 +1,2 @@ -This is the header. There isn't yet much in it. You could [edit](edit?page=_header) it to provide internal navigation or branding. +[[Introduction]] | [[User Documentation]] | [[Deploying Smeagol]] | [[Developing Smeagol]] || +This is the header. You could [edit](edit?page=_header) it to provide internal navigation or branding. diff --git a/resources/public/content/_side-bar.md b/resources/public/content/_side-bar.md index 321efc1..a675893 100644 --- a/resources/public/content/_side-bar.md +++ b/resources/public/content/_side-bar.md @@ -1,3 +1,10 @@ -This is the side bar. There's nothing in it yet. You could [edit](edit?page=_side-bar) it to provide internal navigation or branding. +* [[Introduction]] +* [[User Documentation]] +* [[Deploying Smeagol]] +* [[Developing Smeagol]] -If you don't like it on the left, float it to the right (or do something entirely different) by editing the [stylesheet](/edit-css?page=stylesheet). +