Implemented tags
authorTomas Zeman <tzeman@volny.cz>
Thu, 06 Dec 2018 16:18:26 +0100
changeset 13 216da61215db
parent 12 e7512f9dc903
child 14 7c4b05467630
Implemented tags
base/src/sqwl/cms/Layout.scala
base/src/sqwl/cms/Server.scala
base/src/sqwl/cms/layout/ArticlesByTag.scala
base/src/sqwl/cms/layout/PrimaryView.scala
base/src/sqwl/cms/layout/TagCloud.scala
example/content/a1.html
example/content/public/css/site.css
example/src/sqwl/cms/Content.scala
--- a/base/src/sqwl/cms/Layout.scala	Thu Dec 06 15:19:41 2018 +0100
+++ b/base/src/sqwl/cms/Layout.scala	Thu Dec 06 16:18:26 2018 +0100
@@ -27,8 +27,8 @@
         link(rel:="stylesheet", href:=siteCss),
         tags2.title(st match {
           case ViewArticle(v) => s"${v.title} | ${content.appTitleShort}"
-          case ViewCategory(v) => v.name
-          case ViewTag(v) => v.name
+          case ViewCategory(v) => s"${v.name} | ${content.appTitleShort}"
+          case ViewTag(v) => s"${v.name} | ${content.appTitleShort}"
           case Dashboard => content.appTitle
           case News => "Novinky"
         })
@@ -38,7 +38,9 @@
         div(role:="main", cls:="container",
           Categories(content, st),
           ArticlesInCategory(content, st),
-          PrimaryView(content, st)
+          ArticlesByTag(content, st),
+          PrimaryView(content, st),
+          TagCloud(content, st)
         ),
         footer(id:="footer", p(raw("&nbsp;"))),
         script(src:=jquery),
--- a/base/src/sqwl/cms/Server.scala	Thu Dec 06 15:19:41 2018 +0100
+++ b/base/src/sqwl/cms/Server.scala	Thu Dec 06 16:18:26 2018 +0100
@@ -2,7 +2,7 @@
 
 import akka.actor.ActorSystem
 import akka.http.scaladsl.Http
-import akka.http.scaladsl.model.headers.{ETag, EntityTag}
+import akka.http.scaladsl.model.headers.ETag
 import akka.http.scaladsl.model.{ContentTypes, HttpEntity, HttpHeader, HttpResponse}
 import akka.http.scaladsl.server.Directives._
 import akka.stream.{ActorMaterializer, Materializer}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/base/src/sqwl/cms/layout/ArticlesByTag.scala	Thu Dec 06 16:18:26 2018 +0100
@@ -0,0 +1,20 @@
+package sqwl.cms.layout
+
+import scalatags.Text.all._
+import scalatags.Text.{TypedTag, tags2}
+import sqwl.cms._
+
+object ArticlesByTag extends config {
+  def apply(cnt: iContent, st: ViewState): Option[TypedTag[String]] =
+    st match {
+      case ViewTag(t) =>
+        val l = cnt.articlesByTag(t)
+        Some(tags2.section(
+          ul(l.map(art =>
+            li(a(href:=s"/${http.prefix}/${art.pathSegment}", art.title))
+          )),
+          if (l.isEmpty) "Tag není ještě použit." else ""
+      ))
+      case _ => None
+    }
+}
--- a/base/src/sqwl/cms/layout/PrimaryView.scala	Thu Dec 06 15:19:41 2018 +0100
+++ b/base/src/sqwl/cms/layout/PrimaryView.scala	Thu Dec 06 16:18:26 2018 +0100
@@ -4,11 +4,13 @@
 import scalatags.Text.{TypedTag, tags2}
 import sqwl.cms._
 
-object PrimaryView extends config {
+object PrimaryView extends config with UrlScheme {
   def apply(cnt: iContent, st: ViewState): Option[TypedTag[String]] =
     st match {
       case ViewArticle(art) => Some(tags2.section(
         h1(a(href:=s"/${http.prefix}/${art.pathSegment}", art.title)),
+        div(cls:="row", art.tags.map(t =>
+          a(href:=s"/${http.prefix}/$TAG/${t.pathSegment}", cls:="tag", s"(${t.name})"))),
         raw(art.htmlContent)
       ))
       case _ => None
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/base/src/sqwl/cms/layout/TagCloud.scala	Thu Dec 06 16:18:26 2018 +0100
@@ -0,0 +1,19 @@
+package sqwl.cms.layout
+
+import scalatags.Text.all._
+import scalatags.Text.{TypedTag, tags2}
+import sqwl.cms._
+
+object TagCloud extends config with UrlScheme {
+
+  def apply(cnt: iContent, st: ViewState): Option[TypedTag[String]] =
+    st match {
+      case Dashboard => Some(tags2.section(
+        "Tags: ",
+        cnt.tags.map(t =>
+          a(href:=s"/${http.prefix}/$TAG/${t.pathSegment}", cls:="tag", s"(${t.name})"))
+      ))
+      case _ => None
+    }
+
+}
--- a/example/content/a1.html	Thu Dec 06 15:19:41 2018 +0100
+++ b/example/content/a1.html	Thu Dec 06 16:18:26 2018 +0100
@@ -1,7 +1,6 @@
 <div>Article 1</div>
-<p>Lorem ipsum...</div>
+<p>Lorem ipsum...</p>
 <a href="a1/test.txt">test.txt</a>
-
 <em>Latin Lipsum -  Courtesy generator.lorem-ipsum.info</em>
 <p>Lorem ipsum dolor sit amet, has causae expetenda ut, populo facete abhorreant mea id, mundi iuvaret vivendum ex has. Id sed quas mandamus efficiendi, in cibo dicit mea, sed quando nusquam consequuntur in. Fugit decore an eum, graece mollis ius ne? Facete praesent voluptatum ei duo, pro ei fabulas corrumpit aliquando. Quo clita ponderum persecuti id, hinc velit commodo mea at. Eu nec congue regione cotidieque, quo ei omnium laboramus. Cu ius modo suavitate, cu usu veritus quaerendum vituperatoribus.
   </p>
--- a/example/content/public/css/site.css	Thu Dec 06 15:19:41 2018 +0100
+++ b/example/content/public/css/site.css	Thu Dec 06 16:18:26 2018 +0100
@@ -192,4 +192,8 @@
 	text-decoration: none;
 	text-indent: 10px;
 	text-transform: none;
+}
+
+.tag {
+  margin-right: 1em;
 }
\ No newline at end of file
--- a/example/src/sqwl/cms/Content.scala	Thu Dec 06 15:19:41 2018 +0100
+++ b/example/src/sqwl/cms/Content.scala	Thu Dec 06 16:18:26 2018 +0100
@@ -24,6 +24,21 @@
   case object Cat6 extends Category("Category 6")
 }
 
+sealed abstract class Tag(val name: String) extends EnumEntry with iTag
+  with Hyphencase {
+  override def pathSegment: String = entryName
+}
+
+object Tag extends Enum[Tag] {
+  val values = findValues
+  case object Tag1 extends Tag("Tag 1")
+  case object Tag2 extends Tag("Tag 2")
+  case object Tag3 extends Tag("Tag 3")
+  case object Tag4 extends Tag("Tag 4")
+  case object Tag5 extends Tag("Tag 5")
+  case object Tag6 extends Tag("Tag 6")
+}
+
 sealed abstract class Article(val title: String,
   val category: Option[iCategory],
   val tags: Seq[iTag],
@@ -46,30 +61,46 @@
 
 object Article extends Enum[Article] {
   import Category._
+  import  Tag._
   val values = findValues
-  case object A1 extends Article("Article 1", Some(Cat1), Seq())
+  case object A1 extends Article("Article 1", Some(Cat1),
+    Seq(Tag1, Tag2, Tag3))
   case object A2 extends Article("Article 2", Some(Cat1), Seq())
-  case object A3 extends Article("Article 3", Some(Cat1), Seq())
-  case object A4 extends Article("Article 4", Some(Cat2), Seq())
-  case object A5 extends Article("Article 5", Some(Cat2), Seq())
+  case object A3 extends Article("Article 3", Some(Cat1),
+    Seq(Tag4, Tag5))
+  case object A4 extends Article("Article 4", Some(Cat2), Seq(Tag4))
+  case object A5 extends Article("Article 5", Some(Cat2), Seq(Tag5))
 }
 
 object Content extends iContent {
+
   def appTitle: String = "Content management system example"
+
   def appTitleShort: String = "CMS"
+
   def icon =
     ("icon.png", Paths.get("example/content/public/images/icon.png"))
+
   def publicAssets: Path = Paths.get("example/content/public")
+
   def styleSheet =
     ("site.css", Paths.get("example/content/public/css/site.css"))
-  def articlesByTag(t: iTag): Seq[iArticle] = Seq()
+
+  def articlesByTag(t: iTag): Seq[iArticle] =
+    Article.values.filter(_.tags contains(t))
+
   def articlesByCategory(c: iCategory): Seq[iArticle] =
     Article.values.filter(_.category contains(c))
-  def tags: Seq[iTag] = Seq()
+
+  def tags: Seq[iTag] = Tag.values
+
   def categories: Seq[iCategory] = Category.values
+
   def articleByPath(path: String): Option[iArticle] =
     Article.withNameOption(path)
+
   def categoryByPath(path: String): Option[iCategory] =
     Category.withNameOption(path)
-  def tagByPath(path: String): Option[iTag] = None
+
+  def tagByPath(path: String): Option[iTag] = Tag.withNameOption(path)
 }
\ No newline at end of file