From 7047222889934dbec815d6ecc71191729154a12c Mon Sep 17 00:00:00 2001 From: Thibault Duplessis Date: Tue, 7 Sep 2021 17:16:24 +0200 Subject: [PATCH] ublog atom RSS link --- app/controllers/Ublog.scala | 16 +++++++++++- app/views/base/layout.scala | 10 +++++--- app/views/ublog/atom.scala | 51 +++++++++++++++++++++++++++++++++++++ app/views/ublog/blog.scala | 12 ++++++--- conf/routes | 1 + 5 files changed, 82 insertions(+), 8 deletions(-) create mode 100644 app/views/ublog/atom.scala diff --git a/app/controllers/Ublog.scala b/app/controllers/Ublog.scala index 0f85d662ea..0f0736f788 100644 --- a/app/controllers/Ublog.scala +++ b/app/controllers/Ublog.scala @@ -211,8 +211,22 @@ final class Ublog(env: Env) extends LilaController(env) { } } + def userAtom(username: String) = Action.async { + env.user.repo.enabledNamed(username) flatMap { + case None => NotFound.fuccess + case Some(user) => + env.ublog.api.getUserBlog(user) flatMap { blog => + (isBlogVisible(user, blog) ?? env.ublog.paginator.byUser(user, true, 1)) map { posts => + Ok(html.ublog.atom(user, blog, posts.currentPageResults)) as XML + } + } + } + } + + private def isBlogVisible(user: UserModel, blog: UblogBlog) = user.enabled && blog.visible + private def canViewBlogOf(user: UserModel, blog: UblogBlog)(implicit ctx: Context) = - ctx.is(user) || isGranted(_.ModerateBlog) || (user.enabled && blog.visible) + ctx.is(user) || isGranted(_.ModerateBlog) || isBlogVisible(user, blog) private def canViewPost(user: UserModel, blog: UblogBlog)(post: UblogPost)(implicit ctx: Context) = canViewBlogOf(user, blog) && (ctx.is(user) || post.live) diff --git a/app/views/base/layout.scala b/app/views/base/layout.scala index 84320bed73..ece2a47905 100644 --- a/app/views/base/layout.scala +++ b/app/views/base/layout.scala @@ -197,7 +197,8 @@ object layout { chessground: Boolean = true, zoomable: Boolean = false, csp: Option[ContentSecurityPolicy] = None, - wrapClass: String = "" + wrapClass: String = "", + atomLinkTag: Option[Tag] = None )(body: Frag)(implicit ctx: Context): Frag = frag( doctype, @@ -229,11 +230,12 @@ object layout { !robots option raw(""""""), noTranslate, openGraph.map(_.frags), - link( + (atomLinkTag | link( href := routes.Blog.atom, - tpe := "application/atom+xml", - rel := "alternate", st.title := trans.blog.txt() + ))( + tpe := "application/atom+xml", + rel := "alternate" ), ctx.currentBg == "transp" option ctx.pref.bgImgOrDefault map { img => raw( diff --git a/app/views/ublog/atom.scala b/app/views/ublog/atom.scala new file mode 100644 index 0000000000..8b3ae6f42c --- /dev/null +++ b/app/views/ublog/atom.scala @@ -0,0 +1,51 @@ +package views.html.ublog + +import controllers.routes + +import lila.app.templating.Environment._ +import lila.app.ui.ScalatagsTemplate._ +import lila.common.paginator.Paginator +import lila.user.User +import lila.ublog.{ UblogBlog, UblogPost } + +object atom { + + import views.html.base.atom.atomDate + import views.html.ublog.blog.urlOfBlog + import views.html.ublog.post.{ thumbnail, urlOfPost } + + def apply( + user: User, + blog: UblogBlog, + posts: Seq[UblogPost.PreviewPost] + ) = + views.html.base.atom( + elems = posts, + htmlCall = routes.Ublog.index(user.username), + atomCall = routes.Blog.atom, + title = "lichess.org blog", + updated = posts.headOption.flatMap(_.lived).map(_.at) + ) { post => + frag( + tag("id")(s"$netBaseUrl${urlOfBlog(blog)}"), + tag("published")(post.lived.map(_.at) map atomDate), + link( + rel := "alternate", + tpe := "text/html", + href := s"$netBaseUrl${urlOfPost(post)}" + ), + tag("title")(post.title), + // tag("category")( + // tag("term")(doc.getText("blog.category")), + // tag("label")(slugify(~doc.getText("blog.category"))) + // ), + tag("content")(tpe := "html")( + thumbnail(post, _.Large), + "
", // yes, scalatags encodes it. + post.intro + ), + tag("tag")("media:thumbnail")(attr("url") := thumbnail.url(post, _.Large)), + tag("author")(tag("name")(user.titleUsername)) + ) + } +} diff --git a/app/views/ublog/blog.scala b/app/views/ublog/blog.scala index 1f5eee0c8a..644ef677b9 100644 --- a/app/views/ublog/blog.scala +++ b/app/views/ublog/blog.scala @@ -13,18 +13,23 @@ object blog { import views.html.ublog.{ post => postView } - def apply(user: User, blog: UblogBlog, posts: Paginator[UblogPost.PreviewPost])(implicit ctx: Context) = + def apply(user: User, blog: UblogBlog, posts: Paginator[UblogPost.PreviewPost])(implicit ctx: Context) = { + val title = blog.title | "Blog" views.html.base.layout( moreCss = cssTag("ublog"), moreJs = frag( posts.hasNextPage option infiniteScrollTag, ctx.isAuth option jsModule("ublog") ), - title = trans.ublog.xBlog.txt(user.username) + title = title, + atomLinkTag = link( + href := routes.Ublog.userAtom(user.username), + st.title := title + ).some ) { main(cls := "box box-pad page page-small ublog-index")( div(cls := "box__top")( - h1(trans.ublog.xBlog(userLink(user))), + h1(title), if (ctx is user) div(cls := "box__top__actions")( a(href := routes.Ublog.drafts(user.username))(trans.ublog.drafts()), @@ -44,6 +49,7 @@ object blog { ) ) } + } def urlOfBlog(blog: UblogBlog) = blog.id match { case UblogBlog.Id.User(userId) => routes.Ublog.index(usernameOrId(userId)) diff --git a/conf/routes b/conf/routes index 36db114688..0eed4f40b9 100644 --- a/conf/routes +++ b/conf/routes @@ -62,6 +62,7 @@ GET /@/:username/blog controllers.Ublog.index(username: String, GET /@/:username/blog/:slug/:id controllers.Ublog.post(username: String, slug: String, id: String) GET /@/:username/blog/drafts controllers.Ublog.drafts(username: String, page: Int ?= 1) GET /@/:username/blog/new controllers.Ublog.form(username: String) +GET /@/:username/blog.atom controllers.Ublog.userAtom(username: String) POST /ublog/new controllers.Ublog.create GET /ublog/$id<\w{8}>/edit controllers.Ublog.edit(id: String) POST /ublog/$id<\w{8}>/edit controllers.Ublog.update(id: String)