instead of linking to posts only on a user's blog. Ref T681customize-reader
@@ -129,10 +129,10 @@ func handleFetchCollectionOutbox(app *App, w http.ResponseWriter, r *http.Reques | |||
ocp := activitystreams.NewOrderedCollectionPage(accountRoot, "outbox", res.TotalPosts, p) | |||
ocp.OrderedItems = []interface{}{} | |||
posts, err := app.db.GetPosts(c, p, false, true, false) | |||
posts, err := app.db.GetPosts(app.cfg, c, p, false, true, false) | |||
for _, pp := range *posts { | |||
pp.Collection = res | |||
o := pp.ActivityObject() | |||
o := pp.ActivityObject(app.cfg) | |||
a := activitystreams.NewCreateActivity(o) | |||
ocp.OrderedItems = append(ocp.OrderedItems, *a) | |||
} | |||
@@ -524,7 +524,7 @@ func deleteFederatedPost(app *App, p *PublicPost, collID int64) error { | |||
} | |||
p.Collection.hostName = app.cfg.App.Host | |||
actor := p.Collection.PersonObject(collID) | |||
na := p.ActivityObject() | |||
na := p.ActivityObject(app.cfg) | |||
// Add followers | |||
p.Collection.ID = collID | |||
@@ -570,7 +570,7 @@ func federatePost(app *App, p *PublicPost, collID int64, isUpdate bool) error { | |||
} | |||
} | |||
actor := p.Collection.PersonObject(collID) | |||
na := p.ActivityObject() | |||
na := p.ActivityObject(app.cfg) | |||
// Add followers | |||
p.Collection.ID = collID | |||
@@ -224,14 +224,14 @@ func handleViewHome(app *App, w http.ResponseWriter, r *http.Request) error { | |||
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), "")) | |||
p.Banner = template.HTML(applyMarkdown([]byte(banner.Content), "", app.cfg)) | |||
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), "")) | |||
p.Content = template.HTML(applyMarkdown([]byte(content.Content), "", app.cfg)) | |||
// Get error messages | |||
session, err := app.sessionStore.Get(r, cookieName) | |||
@@ -279,7 +279,7 @@ func handleTemplatedPage(app *App, w http.ResponseWriter, r *http.Request, t *te | |||
return err | |||
} | |||
p.ContentTitle = c.Title.String | |||
p.Content = template.HTML(applyMarkdown([]byte(c.Content), "")) | |||
p.Content = template.HTML(applyMarkdown([]byte(c.Content), "", app.cfg)) | |||
p.PlainContent = shortPostDescription(stripmd.Strip(c.Content)) | |||
if !c.Updated.IsZero() { | |||
p.Updated = c.Updated.Format("January 2, 2006") | |||
@@ -496,7 +496,7 @@ func fetchCollectionPosts(app *App, w http.ResponseWriter, r *http.Request) erro | |||
} | |||
} | |||
posts, err := app.db.GetPosts(c, page, isCollOwner, false, false) | |||
posts, err := app.db.GetPosts(app.cfg, c, page, isCollOwner, false, false) | |||
if err != nil { | |||
return err | |||
} | |||
@@ -730,7 +730,7 @@ func handleViewCollection(app *App, w http.ResponseWriter, r *http.Request) erro | |||
return impart.HTTPError{http.StatusFound, redirURL} | |||
} | |||
coll.Posts, _ = app.db.GetPosts(c, page, cr.isCollOwner, false, false) | |||
coll.Posts, _ = app.db.GetPosts(app.cfg, c, page, cr.isCollOwner, false, false) | |||
// Serve collection | |||
displayPage := CollectionPage{ | |||
@@ -825,7 +825,7 @@ func handleViewCollectionTag(app *App, w http.ResponseWriter, r *http.Request) e | |||
coll := newDisplayCollection(c, cr, page) | |||
coll.Posts, _ = app.db.GetPostsTagged(c, tag, page, cr.isCollOwner) | |||
coll.Posts, _ = app.db.GetPostsTagged(app.cfg, c, tag, page, cr.isCollOwner) | |||
if coll.Posts != nil && len(*coll.Posts) == 0 { | |||
return ErrCollectionPageNotFound | |||
} | |||
@@ -29,6 +29,7 @@ import ( | |||
"github.com/writeas/web-core/log" | |||
"github.com/writeas/web-core/query" | |||
"github.com/writeas/writefreely/author" | |||
"github.com/writeas/writefreely/config" | |||
"github.com/writeas/writefreely/key" | |||
) | |||
@@ -105,8 +106,8 @@ type writestore interface { | |||
ClaimPosts(userID int64, collAlias string, posts *[]ClaimPostRequest) (*[]ClaimPostResult, error) | |||
GetPostsCount(c *CollectionObj, includeFuture bool) | |||
GetPosts(c *Collection, page int, includeFuture, forceRecentFirst, includePinned bool) (*[]PublicPost, error) | |||
GetPostsTagged(c *Collection, tag string, page int, includeFuture bool) (*[]PublicPost, error) | |||
GetPosts(cfg *config.Config, c *Collection, page int, includeFuture, forceRecentFirst, includePinned bool) (*[]PublicPost, error) | |||
GetPostsTagged(cfg *config.Config, c *Collection, tag string, page int, includeFuture bool) (*[]PublicPost, error) | |||
GetAPFollowers(c *Collection) (*[]RemoteUser, error) | |||
GetAPActorKeys(collectionID int64) ([]byte, []byte) | |||
@@ -1067,7 +1068,7 @@ func (db *datastore) GetPostsCount(c *CollectionObj, includeFuture bool) { | |||
// It will return future posts if `includeFuture` is true. | |||
// It will include only standard (non-pinned) posts unless `includePinned` is true. | |||
// TODO: change includeFuture to isOwner, since that's how it's used | |||
func (db *datastore) GetPosts(c *Collection, page int, includeFuture, forceRecentFirst, includePinned bool) (*[]PublicPost, error) { | |||
func (db *datastore) GetPosts(cfg *config.Config, c *Collection, page int, includeFuture, forceRecentFirst, includePinned bool) (*[]PublicPost, error) { | |||
collID := c.ID | |||
cf := c.NewFormat() | |||
@@ -1112,7 +1113,7 @@ func (db *datastore) GetPosts(c *Collection, page int, includeFuture, forceRecen | |||
break | |||
} | |||
p.extractData() | |||
p.formatContent(c, includeFuture) | |||
p.formatContent(cfg, c, includeFuture) | |||
posts = append(posts, p.processPost()) | |||
} | |||
@@ -1128,7 +1129,7 @@ func (db *datastore) GetPosts(c *Collection, page int, includeFuture, forceRecen | |||
// given tag. | |||
// It will return future posts if `includeFuture` is true. | |||
// TODO: change includeFuture to isOwner, since that's how it's used | |||
func (db *datastore) GetPostsTagged(c *Collection, tag string, page int, includeFuture bool) (*[]PublicPost, error) { | |||
func (db *datastore) GetPostsTagged(cfg *config.Config, c *Collection, tag string, page int, includeFuture bool) (*[]PublicPost, error) { | |||
collID := c.ID | |||
cf := c.NewFormat() | |||
@@ -1176,7 +1177,7 @@ func (db *datastore) GetPostsTagged(c *Collection, tag string, page int, include | |||
break | |||
} | |||
p.extractData() | |||
p.formatContent(c, includeFuture) | |||
p.formatContent(cfg, c, includeFuture) | |||
posts = append(posts, p.processPost()) | |||
} | |||
@@ -118,7 +118,7 @@ func compileFullExport(app *App, u *User) *ExportUser { | |||
var collObjs []CollectionObj | |||
for _, c := range *colls { | |||
co := &CollectionObj{Collection: c} | |||
co.Posts, err = app.db.GetPosts(&c, 0, true, false, true) | |||
co.Posts, err = app.db.GetPosts(app.cfg, &c, 0, true, false, true) | |||
if err != nil { | |||
log.Error("unable to get collection posts: %v", err) | |||
} | |||
@@ -55,9 +55,9 @@ func ViewFeed(app *App, w http.ResponseWriter, req *http.Request) error { | |||
tag := mux.Vars(req)["tag"] | |||
if tag != "" { | |||
coll.Posts, _ = app.db.GetPostsTagged(c, tag, 1, false) | |||
coll.Posts, _ = app.db.GetPostsTagged(app.cfg, c, tag, 1, false) | |||
} else { | |||
coll.Posts, _ = app.db.GetPosts(c, 1, false, true, false) | |||
coll.Posts, _ = app.db.GetPosts(app.cfg, c, 1, false, true, false) | |||
} | |||
author := "" | |||
@@ -94,7 +94,7 @@ func ViewFeed(app *App, w http.ResponseWriter, req *http.Request) error { | |||
Title: title, | |||
Link: &Link{Href: permalink}, | |||
Description: "<![CDATA[" + stripmd.Strip(p.Content) + "]]>", | |||
Content: applyMarkdown([]byte(p.Content), ""), | |||
Content: applyMarkdown([]byte(p.Content), "", app.cfg), | |||
Author: &Author{author, ""}, | |||
Created: p.Created, | |||
Updated: p.Updated, | |||
@@ -16,6 +16,7 @@ import ( | |||
stripmd "github.com/writeas/go-strip-markdown" | |||
"github.com/writeas/saturday" | |||
"github.com/writeas/web-core/stringmanip" | |||
"github.com/writeas/writefreely/config" | |||
"github.com/writeas/writefreely/parse" | |||
"html" | |||
"html/template" | |||
@@ -34,27 +35,27 @@ var ( | |||
markeddownReg = regexp.MustCompile("<p>(.+)</p>") | |||
) | |||
func (p *Post) formatContent(c *Collection, isOwner bool) { | |||
func (p *Post) formatContent(cfg *config.Config, c *Collection, isOwner bool) { | |||
baseURL := c.CanonicalURL() | |||
if !isSingleUser { | |||
baseURL = "/" + c.Alias + "/" | |||
} | |||
p.HTMLTitle = template.HTML(applyBasicMarkdown([]byte(p.Title.String))) | |||
p.HTMLContent = template.HTML(applyMarkdown([]byte(p.Content), baseURL)) | |||
p.HTMLContent = template.HTML(applyMarkdown([]byte(p.Content), baseURL, cfg)) | |||
if exc := strings.Index(string(p.Content), "<!--more-->"); exc > -1 { | |||
p.HTMLExcerpt = template.HTML(applyMarkdown([]byte(p.Content[:exc]), baseURL)) | |||
p.HTMLExcerpt = template.HTML(applyMarkdown([]byte(p.Content[:exc]), baseURL, cfg)) | |||
} | |||
} | |||
func (p *PublicPost) formatContent(isOwner bool) { | |||
p.Post.formatContent(&p.Collection.Collection, isOwner) | |||
func (p *PublicPost) formatContent(cfg *config.Config, isOwner bool) { | |||
p.Post.formatContent(cfg, &p.Collection.Collection, isOwner) | |||
} | |||
func applyMarkdown(data []byte, baseURL string) string { | |||
return applyMarkdownSpecial(data, false, baseURL) | |||
func applyMarkdown(data []byte, baseURL string, cfg *config.Config) string { | |||
return applyMarkdownSpecial(data, false, baseURL, cfg) | |||
} | |||
func applyMarkdownSpecial(data []byte, skipNoFollow bool, baseURL string) string { | |||
func applyMarkdownSpecial(data []byte, skipNoFollow bool, baseURL string, cfg *config.Config) string { | |||
mdExtensions := 0 | | |||
blackfriday.EXTENSION_TABLES | | |||
blackfriday.EXTENSION_FENCED_CODE | | |||
@@ -74,7 +75,11 @@ func applyMarkdownSpecial(data []byte, skipNoFollow bool, baseURL string) string | |||
md := blackfriday.Markdown([]byte(data), blackfriday.HtmlRenderer(htmlFlags, "", ""), mdExtensions) | |||
if baseURL != "" { | |||
// Replace special text generated by Markdown parser | |||
md = []byte(hashtagReg.ReplaceAll(md, []byte("<a href=\""+baseURL+"tag:$1\" class=\"hashtag\"><span>#</span><span class=\"p-category\">$1</span></a>"))) | |||
tagPrefix := baseURL + "tag:" | |||
if cfg.App.Chorus { | |||
tagPrefix = "/read/t/" | |||
} | |||
md = []byte(hashtagReg.ReplaceAll(md, []byte("<a href=\""+tagPrefix+"$1\" class=\"hashtag\"><span>#</span><span class=\"p-category\">$1</span></a>"))) | |||
} | |||
// Strip out bad HTML | |||
policy := getSanitizationPolicy() | |||
@@ -35,6 +35,7 @@ import ( | |||
"github.com/writeas/web-core/i18n" | |||
"github.com/writeas/web-core/log" | |||
"github.com/writeas/web-core/tags" | |||
"github.com/writeas/writefreely/config" | |||
"github.com/writeas/writefreely/page" | |||
"github.com/writeas/writefreely/parse" | |||
) | |||
@@ -376,7 +377,7 @@ func handleViewPost(app *App, w http.ResponseWriter, r *http.Request) error { | |||
Direction: d, | |||
} | |||
if !isRaw { | |||
post.HTMLContent = template.HTML(applyMarkdown([]byte(content), "")) | |||
post.HTMLContent = template.HTML(applyMarkdown([]byte(content), "", app.cfg)) | |||
} | |||
} | |||
@@ -1032,7 +1033,7 @@ func fetchPost(app *App, w http.ResponseWriter, r *http.Request) error { | |||
} | |||
p.Collection = &CollectionObj{Collection: *coll} | |||
po := p.ActivityObject() | |||
po := p.ActivityObject(app.cfg) | |||
po.Context = []interface{}{activitystreams.Namespace} | |||
return impart.RenderActivityJSON(w, po, http.StatusOK) | |||
} | |||
@@ -1067,7 +1068,7 @@ func (p *PublicPost) CanonicalURL() string { | |||
return p.Collection.CanonicalURL() + p.Slug.String | |||
} | |||
func (p *PublicPost) ActivityObject() *activitystreams.Object { | |||
func (p *PublicPost) ActivityObject(cfg *config.Config) *activitystreams.Object { | |||
o := activitystreams.NewArticleObject() | |||
o.ID = p.Collection.FederatedAPIBase() + "api/posts/" + p.ID | |||
o.Published = p.Created | |||
@@ -1078,7 +1079,7 @@ func (p *PublicPost) ActivityObject() *activitystreams.Object { | |||
} | |||
o.Name = p.DisplayTitle() | |||
if p.HTMLContent == template.HTML("") { | |||
p.formatContent(false) | |||
p.formatContent(cfg, false) | |||
} | |||
o.Content = string(p.HTMLContent) | |||
if p.Language.Valid { | |||
@@ -1093,7 +1094,11 @@ func (p *PublicPost) ActivityObject() *activitystreams.Object { | |||
if isSingleUser { | |||
tagBaseURL = p.Collection.CanonicalURL() + "tag:" | |||
} else { | |||
tagBaseURL = fmt.Sprintf("%s/%s/tag:", p.Collection.hostName, p.Collection.Alias) | |||
if cfg.App.Chorus { | |||
tagBaseURL = fmt.Sprintf("%s/read/t/", p.Collection.hostName) | |||
} else { | |||
tagBaseURL = fmt.Sprintf("%s/%s/tag:", p.Collection.hostName, p.Collection.Alias) | |||
} | |||
} | |||
for _, t := range p.Tags { | |||
o.Tag = append(o.Tag, activitystreams.Tag{ | |||
@@ -1330,14 +1335,14 @@ func viewCollectionPost(app *App, w http.ResponseWriter, r *http.Request) error | |||
fmt.Fprint(w, p.Content) | |||
} else if strings.Contains(r.Header.Get("Accept"), "application/activity+json") { | |||
p.extractData() | |||
ap := p.ActivityObject() | |||
ap := p.ActivityObject(app.cfg) | |||
ap.Context = []interface{}{activitystreams.Namespace} | |||
return impart.RenderActivityJSON(w, ap, http.StatusOK) | |||
} else { | |||
p.extractData() | |||
p.Content = strings.Replace(p.Content, "<!--more-->", "", 1) | |||
// TODO: move this to function | |||
p.formatContent(cr.isCollOwner) | |||
p.formatContent(app.cfg, cr.isCollOwner) | |||
tp := struct { | |||
*PublicPost | |||
page.StaticPage | |||
@@ -100,7 +100,7 @@ func (app *App) FetchPublicPosts() (interface{}, error) { | |||
} | |||
p.extractData() | |||
p.HTMLContent = template.HTML(applyMarkdown([]byte(p.Content), "")) | |||
p.HTMLContent = template.HTML(applyMarkdown([]byte(p.Content), "", app.cfg)) | |||
fp := p.processPost() | |||
if isCollectionPost { | |||
fp.Collection = &CollectionObj{Collection: *c} | |||
@@ -295,7 +295,7 @@ func viewLocalTimelineFeed(app *App, w http.ResponseWriter, req *http.Request) e | |||
Title: title, | |||
Link: &Link{Href: permalink}, | |||
Description: "<![CDATA[" + stripmd.Strip(p.Content) + "]]>", | |||
Content: applyMarkdown([]byte(p.Content), ""), | |||
Content: applyMarkdown([]byte(p.Content), "", app.cfg), | |||
Author: &Author{author, ""}, | |||
Created: p.Created, | |||
Updated: p.Updated, | |||
@@ -66,7 +66,7 @@ func handleViewSitemap(app *App, w http.ResponseWriter, r *http.Request) error { | |||
host = c.CanonicalURL() | |||
sm := buildSitemap(host, pre) | |||
posts, err := app.db.GetPosts(c, 0, false, false, false) | |||
posts, err := app.db.GetPosts(app.cfg, c, 0, false, false, false) | |||
if err != nil { | |||
log.Error("Error getting posts: %v", err) | |||
return err | |||