shithub: hugo

Download patch

ref: 75a2e6d4e808ab585c10dc330f9ab2f6c4619411
parent: d9b5f9cd9e2807555c428b3df40035086bafec4f
author: spf13 <[email protected]>
date: Thu Jul 11 18:04:57 EDT 2013

Now support for config files as yaml, json or toml

--- a/README.md
+++ b/README.md
@@ -102,16 +102,48 @@
 configuration for a site. In fact a config file isn't even needed for many websites
 since the defaults used follow commonly used patterns.
 
-The following is an example of a config file with the default values
+**Please note the field names must be all lowercase**
 
+### Config Examples
+
+The following is an example of a yaml config file with the default values: 
+    ---
+    sourcedir: "content"
+    layoutdir: "layouts"
+    publishdir: "public"
+    builddrafts: false
+    indexes:
+       category: "categories"
+       tag: "tags"
+    baseurl: "http://yoursite.com/"
+    ...
+
+
+The following is an example of a json config file with the default values: 
     {
-        "SourceDir" : "content",
-        "LayoutDir" : "layouts",
-        "PublishDir" : "public",
-        "BuildDrafts" : false,
-        "Tags" : { "category" : "categories", "tag" : "tags" },
-        "BaseUrl"    : "http://yourSite.com/"
+        "sourcedir": "content",
+        "layoutdir": "layouts",
+        "publishdir": "public",
+        "builddrafts": false,
+        "indexes": {
+           category: "categories",
+           tag: "tags"
+        },
+        "baseurl": "http://yoursite.com/"
     }
+
+
+The following is an example of a toml config file with the default values: 
+
+    sourcedir = "content"
+    layoutdir = "layouts"
+    publishdir = "public"
+    builddrafts = false
+    baseurl = "http://yoursite.com/"
+    [indexes]
+       category = "categories"
+       tag = "tags"
+
 
 ## Usage 
 Make sure either hugo is in your path or provide a path to it.
--- a/docs/content/doc/configuration.md
+++ b/docs/content/doc/configuration.md
@@ -7,15 +7,50 @@
 configuration for a site. In fact a config file isn't even needed for many websites
 since the defaults used follow commonly used patterns.
 
-The following is an example of a config file with the default values: 
+Hugo expects to find the config file in the root of the source directory and
+will look there first for a config.yaml file. If none is present it will
+then look for a config.json file, followed by a config.toml file.
 
-    SourceDir: "content"
-    LayoutDir: "layouts"
-    PublishDir: "public"
-    BuildDrafts: false
-    Tags:
+**Please note the field names must be all lowercase**
+
+## Examples
+
+The following is an example of a yaml config file with the default values: 
+    ---
+    sourcedir: "content"
+    layoutdir: "layouts"
+    publishdir: "public"
+    builddrafts: false
+    indexes:
        category: "categories"
        tag: "tags"
-    BaseUrl: "http://yourSite.com/"
+    baseurl: "http://yoursite.com/"
     ...
+
+
+The following is an example of a json config file with the default values: 
+    {
+        "sourcedir": "content",
+        "layoutdir": "layouts",
+        "publishdir": "public",
+        "builddrafts": false,
+        "indexes": {
+           category: "categories",
+           tag: "tags"
+        },
+        "baseurl": "http://yoursite.com/"
+    }
+
+
+The following is an example of a toml config file with the default values: 
+
+    sourcedir = "content"
+    layoutdir = "layouts"
+    publishdir = "public"
+    builddrafts = false
+    baseurl = "http://yoursite.com/"
+    [indexes]
+       category = "categories"
+       tag = "tags"
+
 
--- a/hugolib/config.go
+++ b/hugolib/config.go
@@ -15,6 +15,8 @@
 
 import (
 	"launchpad.net/goyaml"
+	"github.com/BurntSushi/toml"
+	"encoding/json"
 	"fmt"
 	"io/ioutil"
 	"os"
@@ -26,6 +28,8 @@
 type Config struct {
 	SourceDir, PublishDir, BaseUrl, StaticDir string
 	Path, CacheDir, LayoutDir, DefaultLayout  string
+    ConfigFile                                string
+    Title                                     string
 	Indexes                                   map[string]string // singular, plural
 	ProcessFilters                            map[string][]string
 	BuildDrafts                               bool
@@ -37,7 +41,8 @@
 func SetupConfig(cfgfile *string, path *string) *Config {
 	c.setPath(*path)
 
-	configPath, err := c.findConfigFile(*cfgfile)
+    cfg , err := c.findConfigFile(*cfgfile)
+    c.ConfigFile = cfg
 
 	if err != nil {
 		fmt.Printf("%v", err)
@@ -45,7 +50,6 @@
 	}
 
 	// set defaults
-
 	c.SourceDir = "content"
 	c.LayoutDir = "layouts"
 	c.PublishDir = "public"
@@ -53,13 +57,7 @@
 	c.DefaultLayout = "post"
 	c.BuildDrafts = false
 
-	file, err := ioutil.ReadFile(configPath)
-	if err == nil {
-		if err := goyaml.Unmarshal(file, &c); err != nil {
-			fmt.Printf("Error parsing config: %s", err)
-			os.Exit(1)
-		}
-	}
+    c.readInConfig()
 
 	// set index defaults if none provided
 	if len(c.Indexes) == 0 {
@@ -70,6 +68,32 @@
 	return &c
 }
 
+func (c *Config) readInConfig() {
+    file, err := ioutil.ReadFile(c.ConfigFile)
+    if err == nil {
+        switch path.Ext(c.ConfigFile) {
+            case ".yaml":
+                if err := goyaml.Unmarshal(file, &c); err != nil {
+                    fmt.Printf("Error parsing config: %s", err)
+                    os.Exit(1)
+                }
+
+            case ".json":
+                if err := json.Unmarshal(file, &c); err != nil {
+                    fmt.Printf("Error parsing config: %s", err)
+                    os.Exit(1)
+                }
+
+            case ".toml":
+                if _, err := toml.Decode(string(file), &c); err != nil {
+                    fmt.Printf("Error parsing config: %s", err)
+                    os.Exit(1)
+                }
+        }
+    }
+    Printer(c)
+}
+
 func (c *Config) setPath(p string) {
 	if p == "" {
 		path, err := FindPath()
@@ -126,18 +150,34 @@
 }
 
 func (c *Config) findConfigFile(configFileName string) (string, error) {
-	// If the full path is given, just use that
-	if path.IsAbs(configFileName) {
-		return configFileName, nil
-	}
 
-	// Else check the local directory
-	t := c.GetAbsPath(configFileName)
-	if b, _ := exists(t); b {
-		return t, nil
-	} else {
-		return "", fmt.Errorf("config file not found at: %s", t)
-	}
+    if configFileName == "" { // config not specified, let's search
+        if b, _ := exists(c.GetAbsPath("config.json")); b {
+            return c.GetAbsPath("config.json"), nil
+        }
 
-	return "", nil // This line won't ever happen.. looking forward to go 1.1 when I don't need it
+        if b, _ := exists(c.GetAbsPath("config.toml")); b {
+            return c.GetAbsPath("config.toml"), nil
+        } 
+
+        if b, _ := exists(c.GetAbsPath("config.yaml")); b {
+            return c.GetAbsPath("config.yaml"), nil
+        }
+
+        return "", fmt.Errorf("config file not found in: %s", c.GetPath())
+
+    } else {
+        // If the full path is given, just use that
+        if path.IsAbs(configFileName) {
+            return configFileName, nil
+        }
+
+        // Else check the local directory
+        t := c.GetAbsPath(configFileName)
+        if b, _ := exists(t); b {
+            return t, nil
+        } else {
+            return "", fmt.Errorf("config file not found at: %s", t)
+        }
+    }
 }
--- a/hugolib/site.go
+++ b/hugolib/site.go
@@ -45,6 +45,7 @@
 	Indexes    *OrderedIndexList
 	Recent     *Pages
 	LastChange time.Time
+    Title      string
 }
 
 func (s *Site) getFromIndex(kind string, name string) Pages {
@@ -163,7 +164,7 @@
 
 	filepath.Walk(s.c.GetAbsPath(s.c.SourceDir), walker)
 
-	s.Info = SiteInfo{BaseUrl: template.URL(s.c.BaseUrl)}
+    s.Info = SiteInfo{BaseUrl: template.URL(s.c.BaseUrl), Title: s.c.Title}
 
 	s.Shortcodes = make(map[string]ShortcodeFunc)
 }
@@ -308,7 +309,7 @@
 
 func (s *Site) RenderHomePage() {
 	n := s.NewNode()
-	n.Title = ""
+	n.Title = n.Site.Title
 	n.Url = Urlize(string(n.Site.BaseUrl))
 	n.RSSlink = template.HTML(MakePermalink(string(n.Site.BaseUrl), string("/index.xml")))
 	n.Permalink = template.HTML(string(n.Site.BaseUrl))
--- a/main.go
+++ b/main.go
@@ -26,13 +26,9 @@
 	"time"
 )
 
-const (
-	cfgFiledefault = "config.yaml"
-)
-
 var (
 	baseUrl    = flag.String("b", "", "hostname (and path) to the root eg. http://spf13.com/")
-	cfgfile    = flag.String("c", cfgFiledefault, "config file (default is path/config.yaml)")
+	cfgfile    = flag.String("c", "", "config file (default is path/config.yaml|json|toml)")
 	checkMode  = flag.Bool("k", false, "analyze content and provide feedback")
 	draft      = flag.Bool("d", false, "include content marked as draft")
 	help       = flag.Bool("h", false, "show this help")