summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--system/api/handlers.go26
-rw-r--r--system/db/content.go35
2 files changed, 61 insertions, 0 deletions
diff --git a/system/api/handlers.go b/system/api/handlers.go
index c238ca9..7a2073d 100644
--- a/system/api/handlers.go
+++ b/system/api/handlers.go
@@ -91,6 +91,12 @@ func contentHandler(res http.ResponseWriter, req *http.Request) {
q := req.URL.Query()
id := q.Get("id")
t := q.Get("type")
+ slug := q.Get("slug")
+
+ if slug != "" {
+ contentHandlerBySlug(res, req)
+ return
+ }
if _, ok := content.Types[t]; !ok {
res.WriteHeader(http.StatusNotFound)
@@ -117,6 +123,26 @@ func contentHandler(res http.ResponseWriter, req *http.Request) {
sendData(res, j, http.StatusOK)
}
+func contentHandlerBySlug(res http.ResponseWriter, req *http.Request) {
+ slug := req.URL.Query().Get("slug")
+
+ // lookup type:id by slug key in __contentIndex
+ post, err := db.ContentBySlug(slug)
+ if err != nil {
+ log.Println("Error finding content by slug:", slug, err)
+ res.WriteHeader(http.StatusInternalServerError)
+ return
+ }
+
+ j, err := fmtJSON(json.RawMessage(post))
+ if err != nil {
+ res.WriteHeader(http.StatusInternalServerError)
+ return
+ }
+
+ sendData(res, j, http.StatusOK)
+}
+
func fmtJSON(data ...json.RawMessage) ([]byte, error) {
var msg = []json.RawMessage{}
for _, d := range data {
diff --git a/system/db/content.go b/system/db/content.go
index 0661556..87b3e69 100644
--- a/system/db/content.go
+++ b/system/db/content.go
@@ -229,6 +229,41 @@ func Content(target string) ([]byte, error) {
return val.Bytes(), nil
}
+// ContentBySlug does a lookup in the content index to find the type and id of
+// the requested content. Subsequently, issues the lookup in the type bucket and
+// returns the data at that ID or nil if nothing exists.
+func ContentBySlug(slug string) ([]byte, error) {
+ val := &bytes.Buffer{}
+ err := store.View(func(tx *bolt.Tx) error {
+ var t, id string
+ b := tx.Bucket([]byte("__contentIndex"))
+ idx := b.Get([]byte(slug))
+
+ if idx != nil {
+ tid := strings.Split(string(idx), ":")
+
+ if len(tid) < 2 {
+ return fmt.Errorf("Bad data in content index for slug: %s", slug)
+ }
+
+ t, id = tid[0], tid[1]
+ }
+
+ c := tx.Bucket([]byte(t))
+ _, err := val.Write(c.Get([]byte(id)))
+ if err != nil {
+ return err
+ }
+
+ return nil
+ })
+ if err != nil {
+ return nil, err
+ }
+
+ return val.Bytes(), nil
+}
+
// ContentAll retrives all items from the database within the provided namespace
func ContentAll(namespace string) [][]byte {
var posts [][]byte