mirror of
https://github.com/writefreely/writefreely
synced 2024-11-28 11:30:18 +00:00
Merge pull request #131 from writeas/customize-landing
Customize landing page Resolves T565
This commit is contained in:
commit
7240bf0cdc
6 changed files with 141 additions and 33 deletions
25
admin.go
25
admin.go
|
@ -299,6 +299,7 @@ func handleViewAdminPage(app *App, u *User, w http.ResponseWriter, r *http.Reque
|
|||
Config config.AppCfg
|
||||
Message string
|
||||
|
||||
Banner *instanceContent
|
||||
Content *instanceContent
|
||||
}{
|
||||
Config: app.cfg.App,
|
||||
|
@ -311,6 +312,13 @@ func handleViewAdminPage(app *App, u *User, w http.ResponseWriter, r *http.Reque
|
|||
p.Content, err = getAboutPage(app)
|
||||
} else if slug == "privacy" {
|
||||
p.Content, err = getPrivacyPage(app)
|
||||
} else if slug == "landing" {
|
||||
p.Banner, err = getLandingBanner(app)
|
||||
if err != nil {
|
||||
return impart.HTTPError{http.StatusInternalServerError, fmt.Sprintf("Could not get banner: %v", err)}
|
||||
}
|
||||
p.Content, err = getLandingBody(app)
|
||||
p.Content.ID = "landing"
|
||||
} else {
|
||||
p.Content, err = app.db.GetDynamicContent(slug)
|
||||
}
|
||||
|
@ -334,13 +342,24 @@ func handleAdminUpdateSite(app *App, u *User, w http.ResponseWriter, r *http.Req
|
|||
id := vars["page"]
|
||||
|
||||
// Validate
|
||||
if id != "about" && id != "privacy" {
|
||||
if id != "about" && id != "privacy" && id != "landing" {
|
||||
return impart.HTTPError{http.StatusNotFound, "No such page."}
|
||||
}
|
||||
|
||||
// Update page
|
||||
var err error
|
||||
m := ""
|
||||
err := app.db.UpdateDynamicContent(id, r.FormValue("title"), r.FormValue("content"), "page")
|
||||
if id == "landing" {
|
||||
// Handle special landing page
|
||||
err = app.db.UpdateDynamicContent("landing-banner", "", r.FormValue("banner"), "section")
|
||||
if err != nil {
|
||||
m = "?m=" + err.Error()
|
||||
return impart.HTTPError{http.StatusFound, "/admin/page/" + id + m}
|
||||
}
|
||||
err = app.db.UpdateDynamicContent("landing-body", "", r.FormValue("content"), "section")
|
||||
} else {
|
||||
// Update page
|
||||
err = app.db.UpdateDynamicContent(id, r.FormValue("title"), r.FormValue("content"), "page")
|
||||
}
|
||||
if err != nil {
|
||||
m = "?m=" + err.Error()
|
||||
}
|
||||
|
|
39
app.go
39
app.go
|
@ -186,23 +186,46 @@ func handleViewHome(app *App, w http.ResponseWriter, r *http.Request) error {
|
|||
}
|
||||
|
||||
// Multi-user instance
|
||||
u := getUserSession(app, r)
|
||||
if u != nil {
|
||||
// User is logged in, so show the Pad
|
||||
return handleViewPad(app, w, r)
|
||||
}
|
||||
forceLanding := r.FormValue("landing") == "1"
|
||||
if !forceLanding {
|
||||
// Show correct page based on user auth status and configured landing path
|
||||
u := getUserSession(app, r)
|
||||
if u != nil {
|
||||
// User is logged in, so show the Pad
|
||||
return handleViewPad(app, w, r)
|
||||
}
|
||||
|
||||
if land := app.cfg.App.LandingPath(); land != "/" {
|
||||
return impart.HTTPError{http.StatusFound, land}
|
||||
if land := app.cfg.App.LandingPath(); land != "/" {
|
||||
return impart.HTTPError{http.StatusFound, land}
|
||||
}
|
||||
}
|
||||
|
||||
p := struct {
|
||||
page.StaticPage
|
||||
Flashes []template.HTML
|
||||
Banner template.HTML
|
||||
Content template.HTML
|
||||
|
||||
ForcedLanding bool
|
||||
}{
|
||||
StaticPage: pageForReq(app, r),
|
||||
StaticPage: pageForReq(app, r),
|
||||
ForcedLanding: forceLanding,
|
||||
}
|
||||
|
||||
banner, err := getLandingBanner(app)
|
||||
if err != nil {
|
||||
log.Error("unable to get landing banner: %v", err)
|
||||
return impart.HTTPError{http.StatusInternalServerError, fmt.Sprintf("Could not get banner: %v", err)}
|
||||
}
|
||||
p.Banner = template.HTML(applyMarkdown([]byte(banner.Content), ""))
|
||||
|
||||
content, err := getLandingBody(app)
|
||||
if err != nil {
|
||||
log.Error("unable to get landing content: %v", err)
|
||||
return impart.HTTPError{http.StatusInternalServerError, fmt.Sprintf("Could not get content: %v", err)}
|
||||
}
|
||||
p.Content = template.HTML(applyMarkdown([]byte(content.Content), ""))
|
||||
|
||||
// Get error messages
|
||||
session, err := app.sessionStore.Get(r, cookieName)
|
||||
if err != nil {
|
||||
|
|
56
pages.go
56
pages.go
|
@ -79,3 +79,59 @@ We store log files, or data about what happens on our servers. We also use cooki
|
|||
|
||||
Beyond this, it's important that you trust whoever runs **` + cfg.App.SiteName + `**. Software can only do so much to protect you -- your level of privacy protections will ultimately fall on the humans that run this particular service.`
|
||||
}
|
||||
|
||||
func getLandingBanner(app *App) (*instanceContent, error) {
|
||||
c, err := app.db.GetDynamicContent("landing-banner")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if c == nil {
|
||||
c = &instanceContent{
|
||||
ID: "landing-banner",
|
||||
Type: "section",
|
||||
Content: defaultLandingBanner(app.cfg),
|
||||
Updated: defaultPageUpdatedTime,
|
||||
}
|
||||
}
|
||||
return c, nil
|
||||
}
|
||||
|
||||
func getLandingBody(app *App) (*instanceContent, error) {
|
||||
c, err := app.db.GetDynamicContent("landing-body")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if c == nil {
|
||||
c = &instanceContent{
|
||||
ID: "landing-body",
|
||||
Type: "section",
|
||||
Content: defaultLandingBody(app.cfg),
|
||||
Updated: defaultPageUpdatedTime,
|
||||
}
|
||||
}
|
||||
return c, nil
|
||||
}
|
||||
|
||||
func defaultLandingBanner(cfg *config.Config) string {
|
||||
if cfg.App.Federation {
|
||||
return "# Start your blog in the fediverse"
|
||||
}
|
||||
return "# Start your blog"
|
||||
}
|
||||
|
||||
func defaultLandingBody(cfg *config.Config) string {
|
||||
if cfg.App.Federation {
|
||||
return `## Join the Fediverse
|
||||
|
||||
The fediverse is a large network of platforms that all speak a common language. Imagine if you could reply to Instagram posts from Twitter, or interact with your favorite Medium blogs from Facebook -- federated alternatives like [PixelFed](https://pixelfed.org), [Mastodon](https://joinmastodon.org), and WriteFreely enable you to do these types of things.
|
||||
|
||||
<div style="text-align:center">
|
||||
<iframe style="width: 560px; height: 315px; max-width: 100%;" sandbox="allow-same-origin allow-scripts" src="https://video.writeas.org/videos/embed/cc55e615-d204-417c-9575-7b57674cc6f3" frameborder="0" allowfullscreen></iframe>
|
||||
</div>
|
||||
|
||||
## Write More Socially
|
||||
|
||||
WriteFreely can communicate with other federated platforms like Mastodon, so people can follow your blogs, bookmark their favorite posts, and boost them to their followers. Sign up above to create a blog and join the fediverse.`
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
|
|
@ -53,15 +53,22 @@ tr.subscription {
|
|||
form dd {
|
||||
margin: 0;
|
||||
}
|
||||
.banner-container {
|
||||
text-align: left;
|
||||
}
|
||||
.banner-container h1 {
|
||||
margin-top: 0;
|
||||
max-width: 8em;
|
||||
}
|
||||
</style>
|
||||
{{end}}
|
||||
{{define "content"}}
|
||||
<div id="pricing" class="content-container wide-form">
|
||||
|
||||
<div class="row">
|
||||
<div style="text-align:left">
|
||||
<h1 style="margin-top:0;max-width:8em;">{{if .Federation}}Start your blog in the fediverse{{else}}Start your blog{{end}}</h1>
|
||||
<p><a href="{{if .Federation}}#more{{else}}/about{{end}}">Learn more...</a></p>
|
||||
<div class="banner-container">
|
||||
{{.Banner}}
|
||||
<p><a href="{{if .Content}}#more{{else}}/about{{end}}">Learn more...</a></p>
|
||||
</div>
|
||||
|
||||
<div{{if not .OpenRegistration}} style="padding: 2em 0;"{{end}}>
|
||||
|
@ -76,20 +83,20 @@ form dd {
|
|||
<label>
|
||||
<dt>Username</dt>
|
||||
<dd>
|
||||
<input type="text" id="alias" name="alias" style="width: 100%; box-sizing: border-box;" tabindex="1" autofocus />
|
||||
<input type="text" id="alias" name="alias" style="width: 100%; box-sizing: border-box;" tabindex="1" autofocus {{if .ForcedLanding}}disabled{{end}} />
|
||||
{{if .Federation}}<p id="alias-site" class="demo">@<strong>your-username</strong>@{{.FriendlyHost}}</p>{{else}}<p id="alias-site" class="demo">{{.FriendlyHost}}/<strong>your-username</strong></p>{{end}}
|
||||
</dd>
|
||||
</label>
|
||||
<label>
|
||||
<dt>Password</dt>
|
||||
<dd><input type="password" id="password" name="pass" autocomplete="new-password" placeholder="" tabindex="2" style="width: 100%; box-sizing: border-box;" /></dd>
|
||||
<dd><input type="password" id="password" name="pass" autocomplete="new-password" placeholder="" tabindex="2" style="width: 100%; box-sizing: border-box;" {{if .ForcedLanding}}disabled{{end}} /></dd>
|
||||
</label>
|
||||
<label>
|
||||
<dt>Email (optional)</dt>
|
||||
<dd><input type="email" name="email" id="email" style="letter-spacing: 1px; width: 100%; box-sizing: border-box;" placeholder="me@example.com" tabindex="3" /></dd>
|
||||
<dd><input type="email" name="email" id="email" style="letter-spacing: 1px; width: 100%; box-sizing: border-box;" placeholder="me@example.com" tabindex="3" {{if .ForcedLanding}}disabled{{end}} /></dd>
|
||||
</label>
|
||||
<dt>
|
||||
<button id="btn-create" type="submit" style="margin-top: 0">Create blog</button>
|
||||
<button id="btn-create" type="submit" style="margin-top: 0" {{if .ForcedLanding}}disabled{{end}}>Create blog</button>
|
||||
</dt>
|
||||
</dl>
|
||||
</form>
|
||||
|
@ -101,24 +108,14 @@ form dd {
|
|||
</div>
|
||||
</div>
|
||||
|
||||
{{if .Federation}}
|
||||
{{if .Content}}
|
||||
<a name="more"></a><hr style="margin: 1em auto 3em;" />
|
||||
{{end}}
|
||||
</div>
|
||||
|
||||
{{ if .Federation }}
|
||||
{{ if .Content }}
|
||||
<div class="content-container snug">
|
||||
|
||||
<h2>Join the Fediverse</h2>
|
||||
<p>The fediverse is a large network of platforms that all speak a common language. Imagine if you could reply to Instagram posts from Twitter, or interact with your favorite Medium blogs from Facebook — federated alternatives like <a href="https://pixelfed.org/" target="pixel">PixelFed</a>, <a href="https://joinmastodon.org/" target="masto">Mastodon</a>, and WriteFreely enable you to do these types of things.</p>
|
||||
|
||||
<div style="text-align:center">
|
||||
<iframe style="width: 560px; height: 315px; max-width: 100%;" sandbox="allow-same-origin allow-scripts" src="https://video.writeas.org/videos/embed/cc55e615-d204-417c-9575-7b57674cc6f3" frameborder="0" allowfullscreen></iframe>
|
||||
</div>
|
||||
|
||||
<h2>Write More Socially</h2>
|
||||
<p>WriteFreely can communicate with other federated platforms like Mastodon, so people can follow your blogs, bookmark their favorite posts, and boost them to their followers. Sign up above to create a blog and join the fediverse.</p>
|
||||
|
||||
{{.Content}}
|
||||
</div>
|
||||
{{ end }}
|
||||
|
||||
|
|
|
@ -17,6 +17,9 @@ table.classy.export .disabled, table.classy.export a {
|
|||
<th>Page</th>
|
||||
<th>Last Modified</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="2"><a href="/admin/page/landing">Home</a></td>
|
||||
</tr>
|
||||
{{range .Pages}}
|
||||
<tr>
|
||||
<td><a href="/admin/page/{{.ID}}">{{if .Title.Valid}}{{.Title.String}}{{else}}{{.ID}}{{end}}</a></td>
|
||||
|
|
|
@ -25,23 +25,33 @@ input[type=text] {
|
|||
<div class="snug content-container">
|
||||
{{template "admin-header" .}}
|
||||
|
||||
<h2 id="posts-header">{{.Content.ID}} page</h2>
|
||||
<h2 id="posts-header">{{if eq .Content.ID "landing"}}Home page{{else}}{{.Content.ID}} page{{end}}</h2>
|
||||
|
||||
{{if eq .Content.ID "about"}}
|
||||
<p class="page-desc content-desc">Describe what your instance is <a href="/about" target="page">about</a>.</p>
|
||||
{{else if eq .Content.ID "privacy"}}
|
||||
<p class="page-desc content-desc">Outline your <a href="/privacy" target="page">privacy policy</a>.</p>
|
||||
{{else if eq .Content.ID "landing"}}
|
||||
<p class="page-desc content-desc">Customize your <a href="/?landing=1" target="page">home page</a>.</p>
|
||||
{{end}}
|
||||
|
||||
{{if .Message}}<p>{{.Message}}</p>{{end}}
|
||||
|
||||
<form method="post" action="/admin/update/{{.Content.ID}}" onsubmit="savePage(this)">
|
||||
{{if eq .Content.Type "section"}}
|
||||
<label for="banner">
|
||||
Banner
|
||||
</label>
|
||||
<textarea id="banner" class="section codable norm edit-page" style="min-height: 5em; height: 5em;" name="banner">{{.Banner.Content}}</textarea>
|
||||
<p class="content-desc">We suggest a header (e.g. <code># Welcome</code>), optionally followed by a small bit of text. Accepts Markdown and HTML.</p>
|
||||
{{else}}
|
||||
<label for="title">
|
||||
Title
|
||||
</label>
|
||||
<input type="text" name="title" id="title" value="{{.Content.Title.String}}" />
|
||||
{{end}}
|
||||
<label for="content">
|
||||
Content
|
||||
{{if .Banner}}Body{{else}}Content{{end}}
|
||||
</label>
|
||||
|
||||
<textarea id="content" class="section codable norm edit-page" name="content">{{.Content.Content}}</textarea>
|
||||
|
|
Loading…
Reference in a new issue