试图学习去 - 幽灵到雨果4
#go #ghost #hugo

介绍

在这里我们是once again!如果您错过了最后几篇文章,我建议您先阅读它们,以了解我们的小原型如何发展。这次,我们将进行一些重构以清理一点。我们将要做的大部分是在数据库结构中添加方法。

方法

什么是方法?好吧,您可以将其视为连接到结构的函数。或正如A Tour of Go所说的那样

一种方法是具有特殊接收器参数的函数。

在我们的代码中,我们有一个struct GhostDatabase。我们可以添加具有以下签名的方法,而接收器是我们的结构。

func (gd *GhostDatabase) getLength() int

我们可以用以下方式调用该方法

var db GhostDatabase

...load JSON code here...

length := db.getLength()

好的,我们的完整方法是什么样的?在大多数方法的情况下

func (gd *GhostDatabase) getLength() int {
    return len(gd.Db[0].Data.Posts)
}

许多方法

现在让我们快速淘汰一些有用的方法。在大多数情况下,他们在锡罐上所说的话,所以我不会详细介绍每一个。

func (gd *GhostDatabase) getMobiledoc(i int) string {
    return gd.Db[0].Data.Posts[i].Mobiledoc
}

func (gd *GhostDatabase) getPostId(i int) string {
    return gd.Db[0].Data.Posts[i].ID
}

func (gd *GhostDatabase) getPostTitle(i int) string {
    return gd.Db[0].Data.Posts[i].Title
}

func (gd *GhostDatabase) getPostSlug(i int) string {
    return gd.Db[0].Data.Posts[i].Slug
}

func (gd *GhostDatabase) getPostStatus(i int) string {
    return gd.Db[0].Data.Posts[i].Status
}

func (gd *GhostDatabase) getPostCreatedAt(i int) time.Time {
    return gd.Db[0].Data.Posts[i].CreatedAt
}

func (gd *GhostDatabase) getPostUpdatedAt(i int) time.Time {
    return gd.Db[0].Data.Posts[i].UpdatedAt
}

func (gd *GhostDatabase) getPostPublishedAt(i int) time.Time {
    return gd.Db[0].Data.Posts[i].PublishedAt
}

func (gd *GhostDatabase) getPostFeatureImage(i int) string {
    return gd.Db[0].Data.Posts[i].FeatureImage
}

标签

到目前为止,我们还没有研究的一件事是检索与帖子相关的标签。由于我们现在正在添加方法,这是解决这个问题的好时机。让我们谈谈我们需要做的事情。

首先,我们需要循环浏览帖子标签的数据库。从这里,我们检查一下PostID字段是否与帖子ID匹配pid,我们传递到功能中。然后,我们将标签ID分配给变量,tagId

接下来,我们将通过Tags数据库循环循环,并检查当前标签ID是否与tagId匹配。如果有匹配项,我们将标签名称附加到slice r。完成后,我们返回r

让我们看看实践中的外观。

func (gd *GhostDatabase) getTags(pid string) []string {
    var r []string
    for i := 0; i < len(gd.Db[0].Data.PostsTags); i++ {
        if gd.Db[0].Data.PostsTags[i].PostID == pid {
            tagId := gd.Db[0].Data.PostsTags[i].TagID
            for j := 0; j < len(gd.Db[0].Data.Tags); j++ {
                if gd.Db[0].Data.Tags[j].ID == tagId {
                    r = append(r, gd.Db[0].Data.Tags[j].Name)
                }
            }
        }
    }
    return r
}

不要去破旧。

下次

这就是我们目前的所有方法。我相信,他们不认为我们有所有的零件才能真正开始编写我们的Markdown文件!


享受这篇文章?
How about buying me a coffee?

GitHub logo shindakun / atlg

我一直在Dev.to上介绍的“尝试学习的帖子”的“尝试学习”帖子的来源存储库


代码列表

package main

import (
    "encoding/json"
    "fmt"
    "io"
    "os"
    "reflect"
    "strconv"
    "strings"
    "time"
)

type GhostDatabase struct {
    Db []struct {
        Meta struct {
            ExportedOn int64 `json:"exported_on"`
            Version string `json:"version"`
        } `json:"meta"`
        Data struct {
            Posts []struct {
                ID string `json:"id"`
                UUID string `json:"uuid"`
                Title string `json:"title"`
                Slug string `json:"slug"`
                Mobiledoc string `json:"mobiledoc"`
                HTML string `json:"html"`
                CommentID string `json:"comment_id"`
                Plaintext string `json:"plaintext"`
                FeatureImage string `json:"feature_image"`
                Featured int `json:"featured"`
                Type string `json:"type"`
                Status string `json:"status"`
                Locale interface{} `json:"locale"`
                Visibility string `json:"visibility"`
                EmailRecipientFilter string `json:"email_recipient_filter"`
                AuthorID string `json:"author_id"`
                CreatedAt time.Time `json:"created_at"`
                UpdatedAt time.Time `json:"updated_at"`
                PublishedAt time.Time `json:"published_at"`
                CustomExcerpt interface{} `json:"custom_excerpt"`
                CodeinjectionHead interface{} `json:"codeinjection_head"`
                CodeinjectionFoot interface{} `json:"codeinjection_foot"`
                CustomTemplate interface{} `json:"custom_template"`
                CanonicalURL interface{} `json:"canonical_url"`
            } `json:"posts"`
            PostsAuthors []struct {
                ID string `json:"id"`
                PostID string `json:"post_id"`
                AuthorID string `json:"author_id"`
                SortOrder int `json:"sort_order"`
            } `json:"posts_authors"`
            PostsMeta []interface{} `json:"posts_meta"`
            PostsTags []struct {
                ID string `json:"id"`
                PostID string `json:"post_id"`
                TagID string `json:"tag_id"`
                SortOrder int `json:"sort_order"`
            } `json:"posts_tags"`
            Roles []struct {
                ID string `json:"id"`
                Name string `json:"name"`
                Description string `json:"description"`
                CreatedAt time.Time `json:"created_at"`
                UpdatedAt time.Time `json:"updated_at"`
            } `json:"roles"`
            RolesUsers []struct {
                ID string `json:"id"`
                RoleID string `json:"role_id"`
                UserID string `json:"user_id"`
            } `json:"roles_users"`
            Settings []struct {
                ID string `json:"id"`
                Group string `json:"group"`
                Key string `json:"key"`
                Value string `json:"value"`
                Type string `json:"type"`
                Flags interface{} `json:"flags"`
                CreatedAt time.Time `json:"created_at"`
                UpdatedAt time.Time `json:"updated_at"`
            } `json:"settings"`
            Tags []struct {
                ID string `json:"id"`
                Name string `json:"name"`
                Slug string `json:"slug"`
                Description interface{} `json:"description"`
                FeatureImage interface{} `json:"feature_image"`
                ParentID interface{} `json:"parent_id"`
                Visibility string `json:"visibility"`
                OgImage interface{} `json:"og_image"`
                OgTitle interface{} `json:"og_title"`
                OgDescription interface{} `json:"og_description"`
                TwitterImage interface{} `json:"twitter_image"`
                TwitterTitle interface{} `json:"twitter_title"`
                TwitterDescription interface{} `json:"twitter_description"`
                MetaTitle interface{} `json:"meta_title"`
                MetaDescription interface{} `json:"meta_description"`
                CodeinjectionHead interface{} `json:"codeinjection_head"`
                CodeinjectionFoot interface{} `json:"codeinjection_foot"`
                CanonicalURL interface{} `json:"canonical_url"`
                AccentColor interface{} `json:"accent_color"`
                CreatedAt time.Time `json:"created_at"`
                UpdatedAt time.Time `json:"updated_at"`
            } `json:"tags"`
            Users []struct {
                ID string `json:"id"`
                Name string `json:"name"`
                Slug string `json:"slug"`
                Password string `json:"password"`
                Email string `json:"email"`
                ProfileImage string `json:"profile_image"`
                CoverImage interface{} `json:"cover_image"`
                Bio interface{} `json:"bio"`
                Website interface{} `json:"website"`
                Location interface{} `json:"location"`
                Facebook interface{} `json:"facebook"`
                Twitter interface{} `json:"twitter"`
                Accessibility string `json:"accessibility"`
                Status string `json:"status"`
                Locale interface{} `json:"locale"`
                Visibility string `json:"visibility"`
                MetaTitle interface{} `json:"meta_title"`
                MetaDescription interface{} `json:"meta_description"`
                Tour interface{} `json:"tour"`
                LastSeen time.Time `json:"last_seen"`
                CreatedAt time.Time `json:"created_at"`
                UpdatedAt time.Time `json:"updated_at"`
            } `json:"users"`
        } `json:"data"`
    } `json:"db"`
}

type Mobiledoc struct {
    Version string `json:"version"`
    Markups []interface{} `json:"markups"`
    Atoms []interface{} `json:"atoms"`
    Cards [][]interface{} `json:"cards"`
    Sections [][]interface{} `json:"sections"`
    GhostVersion string `json:"ghostVersion"`
}

func (gd *GhostDatabase) getLength() int {
    return len(gd.Db[0].Data.Posts)
}

func (gd *GhostDatabase) getMobiledoc(i int) string {
    return gd.Db[0].Data.Posts[i].Mobiledoc
}

func (gd *GhostDatabase) getPostId(i int) string {
    return gd.Db[0].Data.Posts[i].ID
}

func (gd *GhostDatabase) getPostTitle(i int) string {
    return gd.Db[0].Data.Posts[i].Title
}

func (gd *GhostDatabase) getPostSlug(i int) string {
    return gd.Db[0].Data.Posts[i].Slug
}

func (gd *GhostDatabase) getPostStatus(i int) string {
    return gd.Db[0].Data.Posts[i].Status
}

func (gd *GhostDatabase) getPostCreatedAt(i int) time.Time {
    return gd.Db[0].Data.Posts[i].CreatedAt
}

func (gd *GhostDatabase) getPostUpdatedAt(i int) time.Time {
    return gd.Db[0].Data.Posts[i].UpdatedAt
}

func (gd *GhostDatabase) getPostPublishedAt(i int) time.Time {
    return gd.Db[0].Data.Posts[i].PublishedAt
}

func (gd *GhostDatabase) getPostFeatureImage(i int) string {
    return gd.Db[0].Data.Posts[i].FeatureImage
}

func (gd *GhostDatabase) getTags(pid string) []string {
    var r []string
    for i := 0; i < len(gd.Db[0].Data.PostsTags); i++ {
        if gd.Db[0].Data.PostsTags[i].PostID == pid {
            tagId := gd.Db[0].Data.PostsTags[i].TagID
            for j := 0; j < len(gd.Db[0].Data.Tags); j++ {
                if gd.Db[0].Data.Tags[j].ID == tagId {
                    r = append(r, gd.Db[0].Data.Tags[j].Name)
                }
            }
        }
    }
    return r
}

func main() {
    fmt.Println("ghost2hugo")

    file, err := os.Open("shindakun-dot-net.ghost.2022-03-18-22-02-58.json")
    if err != nil {
        fmt.Println(err)
    }

    defer file.Close()

    b, err := io.ReadAll(file)
    if err != nil {
        fmt.Println(err)
    }

    var db GhostDatabase

    err = json.Unmarshal(b, &db)
    if err != nil {
        fmt.Println(err)
    }

    for i := 0; i < db.getLength(); i++ {
        fmt.Println(db.getPostTitle(i))
        fmt.Println(db.getPostSlug(i))
        fmt.Println(db.getPostStatus(i))
        fmt.Println(db.getPostCreatedAt(i))
        fmt.Println(db.getPostUpdatedAt(i))
        fmt.Println(db.getPostPublishedAt(i))
        fmt.Println(db.getPostFeatureImage(i))

        id := db.getPostId(i)
        tags := db.getTags(id)
        fmt.Println(tags)

        c := strings.ReplaceAll(db.getMobiledoc(i), "`", "%'")
        cc := "`" + c + "`"

        ucn, err := strconv.Unquote(cc)
        if err != nil {
            fmt.Println(err, ucn)
        }

        ucn = strings.ReplaceAll(ucn, "%'", "`")

        var md Mobiledoc

        err = json.Unmarshal([]byte(ucn), &md)
        if err != nil {
            fmt.Println(err)
        }

        if reflect.ValueOf(md.Cards).Len() > 0 {
            card := md.Cards[0][1]
            bbb := card.(map[string]interface{})

            fmt.Println(bbb["markdown"])
        }

        fmt.Println("---")
    }
}