# HG changeset patch # User Tomas Zeman # Date 1609256807 -3600 # Node ID fa0f19a74283b36eb5a90b906fed6629cec8d23e # Parent 2d14f02ba3bd62b26e94c7d78a947bbaf008cdce CMS API update diff -r 2d14f02ba3bd -r fa0f19a74283 base/resources/config.conf --- a/base/resources/config.conf Tue Nov 24 13:15:49 2020 +0100 +++ b/base/resources/config.conf Tue Dec 29 16:46:47 2020 +0100 @@ -1,10 +1,10 @@ config { + cms { + root = example/content + } http { interface = localhost port = 8080 prefix = cms } - run { - mode = devel - } } diff -r 2d14f02ba3bd -r fa0f19a74283 base/src/sqwl/cms/Server.scala --- a/base/src/sqwl/cms/Server.scala Tue Nov 24 13:15:49 2020 +0100 +++ b/base/src/sqwl/cms/Server.scala Tue Dec 29 16:46:47 2020 +0100 @@ -24,7 +24,6 @@ import scala.collection.immutable import scala.concurrent.ExecutionContextExecutor -import scala.io.StdIn trait Server extends App with Service[Nothing] with config with UrlScheme { @@ -54,7 +53,7 @@ } ~ pathPrefix(asArticle) { article => pathEnd { complete(asHtml(ViewArticle(article))) - } ~ getFromDirectory(article.assets.toString) + } ~ getFromDirectory(content.articleAssets(article).toString) } ~ path(asCategory) { category => complete(asHtml(ViewCategory(category))) } ~ path(TAG / asTag) { tag => @@ -72,10 +71,5 @@ } Http().newServerAt(http.interface, http.port).bind(routes) - if (run.mode == "devel") { - system.log.info("Click `Enter` to close application...") - StdIn.readLine() - system.terminate() - } } diff -r 2d14f02ba3bd -r fa0f19a74283 base/src/sqwl/cms/config.scala --- a/base/src/sqwl/cms/config.scala Tue Nov 24 13:15:49 2020 +0100 +++ b/base/src/sqwl/cms/config.scala Tue Dec 29 16:46:47 2020 +0100 @@ -4,13 +4,14 @@ @conf trait config { + final val cms = new { + val root = "example/content" + } + final val http = new { val interface = "localhost" val port = 8080 val prefix = "cms" } - final val run = new { - val mode = "devel" - } } diff -r 2d14f02ba3bd -r fa0f19a74283 base/src/sqwl/cms/datamodel.scala --- a/base/src/sqwl/cms/datamodel.scala Tue Nov 24 13:15:49 2020 +0100 +++ b/base/src/sqwl/cms/datamodel.scala Tue Dec 29 16:46:47 2020 +0100 @@ -1,7 +1,24 @@ +/* + * Copyright 2018-2020 Tomas Zeman + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package sqwl.cms import java.nio.file.Path +import scalatags.Text.all._ + trait Named { def name: String } @@ -16,10 +33,9 @@ trait iArticle extends Navigable { def title: String - def htmlContent: String + def htmlContent: SeqFrag[Frag] def category: Option[iCategory] def tags: Seq[iTag] - def assets: Path def rank: Int } @@ -36,4 +52,5 @@ def articleByPath(path: String): Option[iArticle] def categoryByPath(path: String): Option[iCategory] def tagByPath(path: String): Option[iTag] + def articleAssets(a: iArticle): Path } diff -r 2d14f02ba3bd -r fa0f19a74283 base/src/sqwl/cms/layout/PrimaryView.scala --- a/base/src/sqwl/cms/layout/PrimaryView.scala Tue Nov 24 13:15:49 2020 +0100 +++ b/base/src/sqwl/cms/layout/PrimaryView.scala Tue Dec 29 16:46:47 2020 +0100 @@ -1,3 +1,18 @@ +/* + * Copyright 2018-2020 Tomas Zeman + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package sqwl.cms.layout import scalatags.Text.all._ @@ -12,7 +27,7 @@ div(cls:="row", div(cls:="col-md-12", art.tags.map(t => a(href:=s"/${http.prefix}/$TAG/${t.pathSegment}", cls:="tag", t.name)))), - raw(art.htmlContent) + art.htmlContent )) case _ => None } diff -r 2d14f02ba3bd -r fa0f19a74283 build.sc --- a/build.sc Tue Nov 24 13:15:49 2020 +0100 +++ b/build.sc Tue Dec 29 16:46:47 2020 +0100 @@ -13,6 +13,8 @@ val akkaVer = "2.6.10" val akkaHttp = "10.2.1" +val topLevelDir: Path = build.millSourcePath + trait Common extends ScalaModule with PublishModule { val scalaVersion = scalaVer @@ -135,9 +137,9 @@ | import sqwl.cms.Category._ | import sqwl.cms.Tag._ | import sqwl.cms.Articles.article - | object `$aid` { + | object `$aid` extends ContentHolder { | implicit val id = Articles.Id("$id") - | twf("${p.toString}") + | val content = twf("${p.toString}") | } | |/* @@ -160,8 +162,10 @@ write(dir / "main.scala", """ | package sqwl.cms - | object Main extends Server { - | override def content: iContent = Content + | import java.nio.file.Paths + | object Main extends Server with config { + | override def content: iContent = + | new Content(Paths.get(cms.root).toAbsolutePath) | } """.stripMargin) @@ -193,20 +197,6 @@ T.sources{ millSourcePath / up / 'example / 'content } } -object production extends Content { - def contentSources: Sources = - T.sources{ millSourcePath / up / 'production / 'content } - - def hgProdId: Input[String] = T.input { - os.proc("hg", "id", "-i", "--cwd", "production").call().out.trim - } - - override def assemblyName: Target[String] = T{ - s"${super.assemblyName()}-${hgProdId()}" - } -} - - object js extends Common with ScalaJSModule { def scalaJSVersion: Target[String] = scalaJsVer } diff -r 2d14f02ba3bd -r fa0f19a74283 example/src/sqwl/cms/Articles.scala --- a/example/src/sqwl/cms/Articles.scala Tue Nov 24 13:15:49 2020 +0100 +++ b/example/src/sqwl/cms/Articles.scala Tue Dec 29 16:46:47 2020 +0100 @@ -1,8 +1,23 @@ +/* + * Copyright 2018-2020 Tomas Zeman + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package sqwl.cms -import java.nio.file.{Path, Paths} +import scalatags.Text.all._ + import scala.collection.mutable -import scalatags.Text.all._ object Articles { case class Id(v: String) @@ -11,10 +26,9 @@ title: String, category: Option[iCategory], tags: Seq[iTag] = Seq(), - htmlContent: String, + htmlContent: SeqFrag[Frag], rank: Int = 0 ) extends iArticle { - override def assets: Path = Paths.get(s"example/content/${id.v}") override def pathSegment: String = id.v } private val all = mutable.ArrayBuffer[iArticle]() @@ -24,7 +38,7 @@ def article(title: String, cat: iCategory, tags: Seq[iTag] = Seq(), rank: Int = 0)(body: Frag*)(implicit articleId: Id): SeqFrag[Frag] = { - all += Article(articleId, title, Option(cat), tags, body.render, rank) + all += Article(articleId, title, Option(cat), tags, body, rank) body } } diff -r 2d14f02ba3bd -r fa0f19a74283 example/src/sqwl/cms/Content.scala --- a/example/src/sqwl/cms/Content.scala Tue Nov 24 13:15:49 2020 +0100 +++ b/example/src/sqwl/cms/Content.scala Tue Dec 29 16:46:47 2020 +0100 @@ -1,7 +1,7 @@ package sqwl.cms -import java.nio.file.{Path, Paths} +import java.nio.file.Path import enumeratum.EnumEntry.Hyphencase import enumeratum._ @@ -38,7 +38,7 @@ case object Tag6 extends Tag("Tag 6") } -object Content extends iContent { +class Content(val root: Path) extends iContent { InitializeContent() def appTitle: String = "Content management system example" @@ -46,12 +46,12 @@ def appTitleShort: String = "CMS" def icon: (String, Path) = - ("icon.png", Paths.get("example/content/public/images/icon.png")) + ("icon.png", root.resolve("public/images/icon.png")) - def publicAssets: Path = Paths.get("example/content/public") + def publicAssets: Path = root.resolve("public") def styleSheet: (String, Path) = - ("site.css", Paths.get("example/content/public/css/site.css")) + ("site.css", root.resolve("public/css/site.css")) def articlesByTag(t: iTag): Seq[iArticle] = Articles.values filter(_.tags contains t) sortBy(_.rank) @@ -70,4 +70,6 @@ Category.withNameOption(path) def tagByPath(path: String): Option[iTag] = Tag.withNameOption(path) + + def articleAssets(a: iArticle): Path = root.resolve(a.pathSegment) } \ No newline at end of file diff -r 2d14f02ba3bd -r fa0f19a74283 example/src/sqwl/cms/ContentHolder.scala --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/example/src/sqwl/cms/ContentHolder.scala Tue Dec 29 16:46:47 2020 +0100 @@ -0,0 +1,23 @@ +/* + * Copyright 2020 Tomas Zeman + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package sqwl.cms + +import scalatags.Text.all._ + +trait ContentHolder { + def id: Articles.Id + def content: SeqFrag[Frag] +}