ponzu-cms / ponzu

Headless CMS with automatic JSON API. Featuring auto-HTTPS from Let's Encrypt, HTTP/2 Server Push, and flexible server framework written in Go.
https://docs.ponzu-cms.org
BSD 3-Clause "New" or "Revised" License
5.67k stars 387 forks source link

Main Field on Content #326

Closed junnotantra closed 4 years ago

junnotantra commented 4 years ago

Hi guys,

I found myself always updating the String() method of every content I've made, to make the listing on admin dashboard readable and SEO friendly slug. Instead of content: abcd-1234-xyz we get content: some pretty title here

So I think it would be great to have this from the start, right after we generate the content. I've made a PR for this on #325 . Let me know what you guys think. :clinking_glasses:

olliephillips commented 4 years ago

That's a really interesting idea and approach.

No time to dig into this at moment, but my initial thoughts, which perhaps you could clarify?

1) What happens if no field is defined as main via the asterisk prefix - what is the default behaviour when a content item is generated?

2) What is the procedure to change the main item once the content item is generated? In the go file itself. How would this be done?

3) What is the impact of content items pushed into Ponzu using the API, rather than the admin UI? Does the code patch cover both routes for data into Ponzu?

nilslice commented 4 years ago

Hi @junnotantra -

Could you post a screen shot of how the CLI operation works (when you create and assign this Main field) and the resulting screen shot of the Admin dashboard where the effect is applied?

I think I understand, but I'm not fully clear on what's happening. Thanks!!

junnotantra commented 4 years ago

Hi ollie,

What happens if no field is defined as main via the asterisk prefix - what is the default behaviour when a content item is generated?

By default it's using UUID, like the current condition

What is the procedure to change the main item once the content item is generated? In the go file itself. How would this be done?

This changes only modify the String() method. Instead of always using UUID, now the user can select which field to be used. Nothing changed if user want to change it from the code. User can just edit it.

What is the impact of content items pushed into Ponzu using the API, rather than the admin UI? Does the code patch cover both routes for data into Ponzu?

This only change the output of generated content file. Should have no impact on writing new content.

junnotantra commented 4 years ago

Hi @nilslice

This is what we get with this command

ponzu gen content review *title:"string" body:"string":richtext rating:"int"

Content listing Screenshot from 2019-10-31 08-25-09

Default slug Screenshot from 2019-10-31 08-25-21

Generated code

package content

import (
    "fmt"

    "github.com/ponzu-cms/ponzu/management/editor"
    "github.com/ponzu-cms/ponzu/system/item"
)

type Review struct {
    item.Item

    Title  string `json:"title"`
    Body   string `json:"body"`
    Rating int    `json:"rating"`
}

// MarshalEditor writes a buffer of html to edit a Review within the CMS
// and implements editor.Editable
func (r *Review) MarshalEditor() ([]byte, error) {
    view, err := editor.Form(r,
        // Take note that the first argument to these Input-like functions
        // is the string version of each Review field, and must follow
        // this pattern for auto-decoding and auto-encoding reasons:
        editor.Field{
            View: editor.Input("Title", r, map[string]string{
                "label":       "Title",
                "type":        "text",
                "placeholder": "Enter the Title here",
            }),
        },
        editor.Field{
            View: editor.Richtext("Body", r, map[string]string{
                "label":       "Body",
                "placeholder": "Enter the Body here",
            }),
        },
        editor.Field{
            View: editor.Input("Rating", r, map[string]string{
                "label":       "Rating",
                "type":        "text",
                "placeholder": "Enter the Rating here",
            }),
        },
    )

    if err != nil {
        return nil, fmt.Errorf("Failed to render Review editor view: %s", err.Error())
    }

    return view, nil
}

func init() {
    item.Types["Review"] = func() interface{} { return new(Review) }
}

// String defines how a Review is printed. Update it using more descriptive
// fields from the Review struct type
func (r *Review) String() string {
    return fmt.Sprintf("Review: %s", r.Title)
}
olliephillips commented 4 years ago

This all works for me. I think as an optional feature it's an intuitive and useful addition to the generate cli. Going to merge it. Thank you!