Browse Source

Moving a bunch of stoff around, getting templating to work more

declaratively, trying to make the site more "site-like" and numerous
other changes
image-sizing
Logan McGrath 12 months ago
parent
commit
15c0dc2e55
  1. 2
      Makefile
  2. 22
      commands.sh
  3. 2
      config.ini
  4. 6
      hie.yaml
  5. 2
      layouts/drafts.html
  6. 33
      logans-site.cabal
  7. 14
      package.yaml
  8. 22
      pages/about-me.md
  9. 2
      site/_posts/2012-11-07-using-perforce-chronicle-for-application-configuration.md
  10. 4
      site/_posts/2012-11-16-scm-backed-application-configuration-with-perforce.md
  11. 2
      site/_posts/2012-11-20-app-config-app-in-action.md
  12. 2
      site/_posts/2012-11-28-promoting-changes-with-app-config-app.md
  13. 2
      site/_posts/2013-06-16-sterling-benchmarks.md
  14. 4
      site/_posts/2013-06-17-sterling-with-memoization.md
  15. 4
      site/_posts/2013-08-05-lessons-from-sterling.md
  16. 1
      site/blog/archives.html
  17. 1
      site/blog/blog.html
  18. 1
      site/blog/drafts.html
  19. 0
      site/code/app-config/index.html
  20. 0
      site/code/app-config/module/controllers/IndexController.php
  21. 0
      site/code/app-config/module/module.ini
  22. 0
      site/code/app-config/module/views/scripts/index/diffs.phtml
  23. 0
      site/code/app-config/module/views/scripts/index/index.phtml
  24. 0
      site/code/app-config/stack_configuration.json
  25. 0
      site/css/_code.sass
  26. 0
      site/css/_default.sass
  27. 0
      site/css/_index.sass
  28. 0
      site/css/_theme.sass
  29. 0
      site/css/main.sass
  30. 0
      site/css/screen-sizes/_huge-format.sass
  31. 0
      site/css/screen-sizes/_large-format.sass
  32. 0
      site/css/screen-sizes/_medium-format.sass
  33. 0
      site/css/screen-sizes/_small-format.sass
  34. 7
      site/gen/_post.md
  35. 0
      site/images/app-config/commit.png
  36. 0
      site/images/app-config/diffs-after-commit.png
  37. 0
      site/images/app-config/diffs.png
  38. 0
      site/images/app-config/history-diffs.png
  39. 0
      site/images/app-config/history.png
  40. 0
      site/images/app-config/start.png
  41. 0
      site/images/app-config2/aardvark_configuration-changed.png
  42. 0
      site/images/app-config2/aardvark_configuration.png
  43. 0
      site/images/app-config2/changes.png
  44. 0
      site/images/app-config2/start.png
  45. 0
      site/images/app-config3/p4v.png
  46. 0
      site/images/app-config3/p4v_integrate.png
  47. 0
      site/images/app-config3/p4v_integrate_result.png
  48. 0
      site/images/app-config3/pending_changes.png
  49. 0
      site/images/app-config3/promote_changes.png
  50. 0
      site/images/app-config3/promote_result.png
  51. 0
      site/images/grass.svg
  52. 0
      site/images/haskell-logo.png
  53. 0
      site/js/main.js
  54. 0
      site/layouts/bare-content.html
  55. 2
      site/layouts/default.html
  56. 0
      site/layouts/post.html
  57. 0
      site/layouts/skeleton.html
  58. 2
      site/pages/404.md
  59. 14
      site/pages/about-me.md
  60. 2
      site/pages/contact.md
  61. 2
      site/pages/index.md
  62. 2
      site/pages/resume.md
  63. 0
      site/partials/footer.html
  64. 0
      site/partials/image.html
  65. 0
      site/partials/post-list.html
  66. 0
      site/partials/post.html
  67. 0
      site/partials/previous-posts.html
  68. 0
      site/partials/source-generated.html
  69. 0
      site/partials/teaser-list.html
  70. 0
      site/partials/youtube.html
  71. 0
      site/templates/robots.txt
  72. 9
      site/templates/sitemap.xml
  73. 31
      src/Site.hs
  74. 14
      src/Site/Common.hs
  75. 25
      src/Site/Compiler/Layout.hs
  76. 9
      src/Site/Compiler/Pandoc.hs
  77. 39
      src/Site/Config.hs
  78. 32
      src/Site/Context.hs
  79. 9
      src/Site/Context/Field.hs
  80. 14
      src/Site/Context/GitCommits.hs
  81. 4
      src/Site/Context/Post.hs
  82. 9
      src/Site/Metadata.hs
  83. 18
      src/Site/Route.hs
  84. 15
      src/Site/Rule.hs
  85. 25
      src/Site/Rule/Archive.hs
  86. 75
      src/Site/Rule/Blog.hs
  87. 25
      src/Site/Rule/Meta.hs
  88. 4
      src/Site/Rule/Page.hs
  89. 16
      src/Site/Rule/Robot.hs
  90. 20
      src/Site/Rule/Sass.hs
  91. 16
      src/Site/Rule/Sitemap.hs
  92. 11
      src/Site/Util.hs
  93. 17
      test/Site/Compiler/LayoutSpec.hs
  94. 25
      test/Site/RouteSpec.hs
  95. 36
      test/Site/Rule/BlogSpec.hs
  96. 186
      test/Site/Spec/Common.hs
  97. 6
      test/data/applyLayoutFromMetadata/content.md
  98. 4
      test/data/applyLayoutFromMetadata/layout.md

2
Makefile

@ -36,4 +36,4 @@ test:
hpack:
stack exec hpack
.PHONY: test
.PHONY: hpack

22
commands.sh

@ -24,7 +24,7 @@ build () {
fi
stack build
stack exec logans-blog-exe build
stack exec logans-site-exe build
}
clean () {
@ -34,7 +34,7 @@ clean () {
clean_all () {
clean
stack clean
rm -rf _site/*
rm -rf _cache/* _site/*
}
rebuild () {
@ -44,21 +44,7 @@ rebuild () {
touch_all () {
# touch all files so they're built again
paths=(
README.md
about-me.md
blog
code
contact.md
css
images
index.md
js
partials
resume.md
templates
)
find "$paths" -type f -exec touch {} +
touch site
}
rebuild_all () {
@ -69,7 +55,7 @@ rebuild_all () {
watch () {
build
stack exec logans-blog-exe watch
stack exec logans-site-exe watch
}
publish () {

2
config.ini

@ -3,9 +3,11 @@ title = This Field Was Green
root = https://thisfieldwas.green
authorName = Logan McGrath
authorEmail = blog@thisfieldwas.green
linkedInProfile = https://www.linkedin.com/in/loganmcgrath
gitWebUrl = https://bitsof.thisfieldwas.green/ThisFieldWasGreen/thisfieldwas.green
[hakyll]
providerDirectory = site
destinationDirectory = _site
allowedFiles = .nojekyll

6
hie.yaml

@ -1,8 +1,8 @@
cradle:
stack:
- path: ./src
component: logans-blog:lib
component: logans-site:lib
- path: ./app
component: logans-blog:exe:logans-blog-exe
component: logans-site:exe:logans-site-exe
- path: ./test
component: logans-blog:test:logans-blog-test
component: logans-site:test:logans-site-test

2
layouts/drafts.html

@ -1,2 +0,0 @@
Here you can find all my drafts:
$partial("partials/post-list.html")$

33
logans-blog.cabal → logans-site.cabal

@ -4,15 +4,15 @@ cabal-version: 1.12
--
-- see: https://github.com/sol/hpack
--
-- hash: d2a97e97f33590b8613bb27a17ceac2489cdfa1c3c7041739f323b91a4d4fb46
-- hash: 9a35c08a9d6989bc59e76bcec423a66ecb6b9ef0cc57cce3fc5d7b1376e0b0cc
name: logans-blog
name: logans-site
version: 0.1.0.0
description: Please see the README at <https://github.com/ThisFieldWasGreen/thisfieldwasgreen.github.io#readme>
homepage: https://github.com/ThisFieldWasGreen/thisfieldwasgreen.github.io#readme
bug-reports: https://github.com/ThisFieldWasGreen/thisfieldwasgreen.github.io/issues
author: Logan McGrath
maintainer: blog@thisfieldwas.green
maintainer: site@thisfieldwas.green
copyright: 2012 Logan McGrath
license: MIT
build-type: Simple
@ -31,23 +31,23 @@ library
Site.Compiler.Layout
Site.Compiler.Pandoc
Site.Config
Site.Context
Site.Context.Field
Site.Context.GitCommits
Site.Context.Post
Site.Context.Tag
Site.Metadata
Site.Route
Site.Rule
Site.Rule.Archive
Site.Rule.Blog
Site.Rule.Feed
Site.Rule.Js
Site.Rule.Meta
Site.Rule.Page
Site.Rule.Robot
Site.Rule.Sass
Site.Rule.Sitemap
Site.Util
other-modules:
Paths_logans_blog
Paths_logans_site
hs-source-dirs:
src
default-extensions:
@ -108,6 +108,7 @@ library
, microlens ==0.4.*
, microlens-th ==0.4.*
, mtl ==2.2.*
, optparse-applicative >=0.12 && <0.17
, pandoc ==2.11.*
, pandoc-types ==1.22.*
, process ==1.6.*
@ -118,12 +119,13 @@ library
, unordered-containers ==0.2.*
, utf8-string ==1.0.*
, vector ==0.12.*
, yaml ==0.11.*
default-language: Haskell2010
executable logans-blog-exe
executable logans-site-exe
main-is: Main.hs
other-modules:
Paths_logans_blog
Paths_logans_site
hs-source-dirs:
app
default-extensions:
@ -221,10 +223,11 @@ executable logans-blog-exe
, hakyll ==4.14.*
, hjsmin ==0.2.*
, language-javascript ==0.7.*
, logans-blog
, logans-site
, microlens ==0.4.*
, microlens-th ==0.4.*
, mtl ==2.2.*
, optparse-applicative >=0.12 && <0.17
, pandoc ==2.11.*
, pandoc-types ==1.22.*
, process ==1.6.*
@ -235,16 +238,18 @@ executable logans-blog-exe
, unordered-containers ==0.2.*
, utf8-string ==1.0.*
, vector ==0.12.*
, yaml ==0.11.*
default-language: Haskell2010
test-suite logans-blog-test
test-suite logans-site-test
type: exitcode-stdio-1.0
main-is: Spec.hs
other-modules:
Site.Compiler.LayoutSpec
Site.RouteSpec
Site.Rule.BlogSpec
Site.Spec.Common
Paths_logans_blog
Paths_logans_site
hs-source-dirs:
test
default-extensions:
@ -344,10 +349,11 @@ test-suite logans-blog-test
, hspec ==2.7.*
, hspec-core ==2.7.*
, language-javascript ==0.7.*
, logans-blog
, logans-site
, microlens ==0.4.*
, microlens-th ==0.4.*
, mtl ==2.2.*
, optparse-applicative >=0.12 && <0.17
, pandoc ==2.11.*
, pandoc-types ==1.22.*
, process ==1.6.*
@ -358,4 +364,5 @@ test-suite logans-blog-test
, unordered-containers ==0.2.*
, utf8-string ==1.0.*
, vector ==0.12.*
, yaml ==0.11.*
default-language: Haskell2010

14
package.yaml

@ -1,9 +1,9 @@
name: logans-blog
name: logans-site
version: 0.1.0.0
github: ThisFieldWasGreen/thisfieldwasgreen.github.io
license: MIT
author: Logan McGrath
maintainer: "blog@thisfieldwas.green"
maintainer: "site@thisfieldwas.green"
copyright: "2012 Logan McGrath"
extra-source-files:
@ -27,6 +27,7 @@ dependencies:
- microlens-th == 0.4.*
- MissingH == 1.4.*
- mtl == 2.2.*
- optparse-applicative >= 0.12 && < 0.17
- pandoc == 2.11.*
- pandoc-types == 1.22.*
- process == 1.6.*
@ -37,6 +38,7 @@ dependencies:
- unordered-containers == 0.2.*
- utf8-string == 1.0.*
- vector == 0.12.*
- yaml == 0.11.*
library:
source-dirs: src
@ -102,21 +104,21 @@ ghc-options: &ghc-options
- -Wunused-type-patterns
executables:
logans-blog-exe:
logans-site-exe:
main: Main.hs
source-dirs: app
default-extensions: *default-extensions
ghc-options: *ghc-options
dependencies:
- logans-blog
- logans-site
tests:
logans-blog-test:
logans-site-test:
main: Spec.hs
source-dirs: test
default-extensions: *default-extensions
ghc-options: *ghc-options
dependencies:
- logans-blog
- logans-site
- hspec == 2.7.*
- hspec-core == 2.7.*

22
pages/about-me.md

@ -1,22 +0,0 @@
---
layout: default
title: "About"
comments: false
sharing: true
footer: true
page-type: static
---
## About
Hi, I'm Logan McGrath, and I'm a software engineer.
Most of my free time is spent in language development. Mostly for learning, but
mostly because I also dream of eventually having something out in the wild. I
write about my learnings in the hope that language development can be more
accessible to the masses. Everyone should be able to contribute to help make our
most core tools more usable and friendly.
More information about me can be found on my [LinkedIn profile][].
[LinkedIn profile]: https://www.linkedin.com/in/loganmcgrath

2
blog/2012-11-07-using-perforce-chronicle-for-application-configuration.md → site/_posts/2012-11-07-using-perforce-chronicle-for-application-configuration.md

@ -2,7 +2,7 @@
layout: post
title: "Using Perforce Chronicle for application configuration"
author: "Logan McGrath"
date: 2012-11-07T13:54:00-05:00
created: 2012-11-07T13:54:00-05:00
published: 2012-11-07T13:54:00-05:00
tags: Perforce, Configuration Management
---

4
blog/2012-11-16-scm-backed-application-configuration-with-perforce.md → site/_posts/2012-11-16-scm-backed-application-configuration-with-perforce.md

@ -2,7 +2,7 @@
layout: post
title: "SCM-Backed Application Configuration with Perforce"
author: "Logan McGrath"
date: 2012-11-16T07:00:00-05:00
created: 2012-11-16T07:00:00-05:00
published: 2012-11-16T07:00:00-05:00
comments: false
tags: SCM, Perforce, Sinatra, AngularJS
@ -170,7 +170,7 @@ existing infrastructure.
The reason I point out Subversion and TFS is largely due to support of
per-branch permissions.
[last post]: $route-to("blog/2012-11-07-using-perforce-chronicle-for-application-configuration.md")$
[last post]: $route-to("posts/2012-11-07-using-perforce-chronicle-for-application-configuration.md")$
[forked]: https://github.com/lmcgrath/App-Config-App/
[AngularJS]: http://angularjs.org/
[App-Config-App's README]: https://github.com/lmcgrath/app-config-app/blob/master/README.md

2
blog/2012-11-20-app-config-app-in-action.md → site/_posts/2012-11-20-app-config-app-in-action.md

@ -2,7 +2,7 @@
layout: post
title: "App-Config-App in Action"
author: "Logan McGrath"
date: 2012-11-20T07:00:00-05:00
created: 2012-11-20T07:00:00-05:00
published: 2012-11-20T07:00:00-05:00
comments: false
tags: AngularJS, Perforce, SCM, Sinatra, Configuration Management

2
blog/2012-11-28-promoting-changes-with-app-config-app.md → site/_posts/2012-11-28-promoting-changes-with-app-config-app.md

@ -2,7 +2,7 @@
layout: post
title: "Promoting changes with App-Config-App"
author: "Logan McGrath"
date: 2012-11-28T13:04:00-05:00
created: 2012-11-28T13:04:00-05:00
published: 2012-11-28T13:04:00-05:00
comments: false
tags: AngularJS, Perforce, SCM, Sinatra, Configuration Management

2
blog/2013-06-16-sterling-benchmarks.md → site/_posts/2013-06-16-sterling-benchmarks.md

@ -1,7 +1,7 @@
---
layout: post
title: "Sterling Benchmarks"
date: 2013-06-16T21:12:00-07:00
created: 2013-06-16T21:12:00-07:00
comments: false
tags: Functional Programming, Sterling, Language Design
---

4
blog/2013-06-17-sterling-with-memoization.md → site/_posts/2013-06-17-sterling-with-memoization.md

@ -2,7 +2,7 @@
layout: post
title: "Sterling With Memoization"
author: "Logan McGrath"
date: 2013-06-17T04:26:00-07:00
created: 2013-06-17T04:26:00-07:00
comments: false
tags: Sterling, Functional Programming, Language Design
---
@ -133,7 +133,7 @@ function should not leverage memoization.
* [Commit containing memoization changes][]
* [Benchmark showing O(1) complexity][]
[last post]: $route-to("blog/2013-06-16-sterling-benchmarks.md")$
[last post]: $route-to("posts/2013-06-16-sterling-benchmarks.md")$
[Sterling]: https://github.com/lmcgrath/sterling
[Memoization]: https://en.wikipedia.org/wiki/Memoization
[Commit containing memoization changes]: https://github.com/lmcgrath/sterling/commit/7d69d49a911d2d916701fa973e02ffabe82afe9d

4
blog/2013-08-05-lessons-from-sterling.md → site/_posts/2013-08-05-lessons-from-sterling.md

@ -2,7 +2,7 @@
layout: post
title: "Lessons from Sterling"
author: "Logan McGrath"
date: 2013-08-05T09:37:00-07:00
created: 2013-08-05T09:37:00-07:00
comments: false
tags: Sterling, Functional Programming, Language Design
---
@ -405,6 +405,6 @@ memoization becomes a near requirement in order to make lazy evaluation useful.
[virtually anywhere for anything]: http://brandonbyars.com/2008/07/21/orthogonality/
[directly into a language]: http://paulhammant.com/blog/crazy-bob-and-type-safety-for-dependency-injection.html/
[open/closed principle]: http://en.wikipedia.org/wiki/Open/closed_principle
[memoization]: $route-to("blog/2013-06-17-sterling-with-memoization.md")$
[memoization]: $route-to("posts/2013-06-17-sterling-with-memoization.md")$
[visitor pattern]: http://en.wikipedia.org/wiki/Visitor_pattern#Java_example
[single dispatch]: http://en.wikipedia.org/wiki/Multiple_dispatch#Java

1
pages/archives.md → site/blog/archives.html

@ -1,6 +1,7 @@
---
layout: default
title: "These Posts Were Green"
updated: 2021-05-24T20:07:11-05:00
---
Here you can find all my previous posts:

1
pages/blog.md → site/blog/blog.html

@ -1,6 +1,7 @@
---
layout: default
title: "This Blog Was Green"
updated: 2021-05-24T20:07:11-05:00
---
$latest-post$

1
pages/drafts.md → site/blog/drafts.html

@ -1,6 +1,7 @@
---
layout: default
title: "These Drafts Are Still Green"
updated: 2021-05-24T20:07:11-05:00
---
Here you can find all my drafts:

0
code/app-config/index.html → site/code/app-config/index.html

0
code/app-config/module/controllers/IndexController.php → site/code/app-config/module/controllers/IndexController.php

0
code/app-config/module/module.ini → site/code/app-config/module/module.ini

0
code/app-config/module/views/scripts/index/diffs.phtml → site/code/app-config/module/views/scripts/index/diffs.phtml

0
code/app-config/module/views/scripts/index/index.phtml → site/code/app-config/module/views/scripts/index/index.phtml

0
code/app-config/stack_configuration.json → site/code/app-config/stack_configuration.json

0
css/_code.sass → site/css/_code.sass

0
css/_default.sass → site/css/_default.sass

0
css/_index.sass → site/css/_index.sass

0
css/_theme.sass → site/css/_theme.sass

0
css/main.sass → site/css/main.sass

0
css/screen-sizes/_huge-format.sass → site/css/screen-sizes/_huge-format.sass

0
css/screen-sizes/_large-format.sass → site/css/screen-sizes/_large-format.sass

0
css/screen-sizes/_medium-format.sass → site/css/screen-sizes/_medium-format.sass

0
css/screen-sizes/_small-format.sass → site/css/screen-sizes/_small-format.sass

7
site/gen/_post.md

@ -0,0 +1,7 @@
---
title: $title$
author: $author$
created: $date$
comments: false
---

0
images/app-config/commit.png → site/images/app-config/commit.png

Before

Width:  |  Height:  |  Size: 307 KiB

After

Width:  |  Height:  |  Size: 307 KiB

0
images/app-config/diffs-after-commit.png → site/images/app-config/diffs-after-commit.png

Before

Width:  |  Height:  |  Size: 64 KiB

After

Width:  |  Height:  |  Size: 64 KiB

0
images/app-config/diffs.png → site/images/app-config/diffs.png

Before

Width:  |  Height:  |  Size: 75 KiB

After

Width:  |  Height:  |  Size: 75 KiB

0
images/app-config/history-diffs.png → site/images/app-config/history-diffs.png

Before

Width:  |  Height:  |  Size: 57 KiB

After

Width:  |  Height:  |  Size: 57 KiB

0
images/app-config/history.png → site/images/app-config/history.png

Before

Width:  |  Height:  |  Size: 26 KiB

After

Width:  |  Height:  |  Size: 26 KiB

0
images/app-config/start.png → site/images/app-config/start.png

Before

Width:  |  Height:  |  Size: 47 KiB

After

Width:  |  Height:  |  Size: 47 KiB

0
images/app-config2/aardvark_configuration-changed.png → site/images/app-config2/aardvark_configuration-changed.png

Before

Width:  |  Height:  |  Size: 58 KiB

After

Width:  |  Height:  |  Size: 58 KiB

0
images/app-config2/aardvark_configuration.png → site/images/app-config2/aardvark_configuration.png

Before

Width:  |  Height:  |  Size: 58 KiB

After

Width:  |  Height:  |  Size: 58 KiB

0
images/app-config2/changes.png → site/images/app-config2/changes.png

Before

Width:  |  Height:  |  Size: 54 KiB

After

Width:  |  Height:  |  Size: 54 KiB

0
images/app-config2/start.png → site/images/app-config2/start.png

Before

Width:  |  Height:  |  Size: 46 KiB

After

Width:  |  Height:  |  Size: 46 KiB

0
images/app-config3/p4v.png → site/images/app-config3/p4v.png

Before

Width:  |  Height:  |  Size: 105 KiB

After

Width:  |  Height:  |  Size: 105 KiB

0
images/app-config3/p4v_integrate.png → site/images/app-config3/p4v_integrate.png

Before

Width:  |  Height:  |  Size: 97 KiB

After

Width:  |  Height:  |  Size: 97 KiB

0
images/app-config3/p4v_integrate_result.png → site/images/app-config3/p4v_integrate_result.png

Before

Width:  |  Height:  |  Size: 32 KiB

After

Width:  |  Height:  |  Size: 32 KiB

0
images/app-config3/pending_changes.png → site/images/app-config3/pending_changes.png

Before

Width:  |  Height:  |  Size: 48 KiB

After

Width:  |  Height:  |  Size: 48 KiB

0
images/app-config3/promote_changes.png → site/images/app-config3/promote_changes.png

Before

Width:  |  Height:  |  Size: 40 KiB

After

Width:  |  Height:  |  Size: 40 KiB

0
images/app-config3/promote_result.png → site/images/app-config3/promote_result.png

Before

Width:  |  Height:  |  Size: 39 KiB

After

Width:  |  Height:  |  Size: 39 KiB

0
images/grass.svg → site/images/grass.svg

Before

Width:  |  Height:  |  Size: 1.0 KiB

After

Width:  |  Height:  |  Size: 1.0 KiB

0
images/haskell-logo.png → site/images/haskell-logo.png

Before

Width:  |  Height:  |  Size: 5.5 KiB

After

Width:  |  Height:  |  Size: 5.5 KiB

0
js/main.js → site/js/main.js

0
layouts/bare-content.html → site/layouts/bare-content.html

2
layouts/default.html → site/layouts/default.html

@ -8,7 +8,7 @@ layout: skeleton
</div>
<nav>
<a href='$route-to("pages/index.md")$'>Home</a>
<a href='$route-to("pages/blog.md")$'>Posts</a>
<a href='$route-to("blog/blog.html")$'>Posts</a>`
<a href='$route-to("pages/about-me.md")$'>About</a>
<a href='$route-to("pages/resume.md")$'>Resume</a>
<a href='$route-to("pages/contact.md")$'>Contact</a>

0
layouts/post.html → site/layouts/post.html

0
layouts/skeleton.html → site/layouts/skeleton.html

2
pages/404.md → site/pages/404.md

@ -1,7 +1,7 @@
---
layout: default
title: "404 Not Found"
page-type: static
updated: 2021-05-24T20:07:11-05:00
---
The resource you were looking for does not exist.

14
site/pages/about-me.md

@ -0,0 +1,14 @@
---
layout: default
title: "About"
updated: 2021-05-24T20:07:11-05:00
comments: false
sharing: true
footer: true
---
Hi, I'm Logan McGrath, and I'm a software engineer.
More information about me can be found on my [LinkedIn profile][].
[LinkedIn profile]: $linkedin-profile$

2
pages/contact.md → site/pages/contact.md

@ -1,7 +1,7 @@
---
layout: default
title: "Contact"
page-type: static
updated: 2021-05-24T20:07:11-05:00
---
I live in a small hut in the mountains of Kumano Kodō on Kii Hantō and would not

2
pages/index.md → site/pages/index.md

@ -1,7 +1,7 @@
---
layout: default
title: "Logan McGrath's Online CV"
page-type: static
updated: 2021-05-24T20:07:11-05:00
---
TODO finish this

2
pages/resume.md → site/pages/resume.md

@ -1,7 +1,7 @@
---
layout: default
title: "Logan McGrath's Online CV"
page-type: static
updated: 2021-05-24T20:07:11-05:00
---
TODO finish this

0
partials/footer.html → site/partials/footer.html

0
partials/image.html → site/partials/image.html

0
partials/post-list.html → site/partials/post-list.html

0
partials/post.html → site/partials/post.html

0
partials/previous-posts.html → site/partials/previous-posts.html

0
partials/source-generated.html → site/partials/source-generated.html

0
partials/teaser-list.html → site/partials/teaser-list.html

0
partials/youtube.html → site/partials/youtube.html

0
meta/robots.txt → site/templates/robots.txt

9
meta/sitemap.xml → site/templates/sitemap.xml

@ -5,17 +5,12 @@
xmlns:mobile="http://www.google.com/schemas/sitemap-mobile/1.0"
xmlns:image="http://www.google.com/schemas/sitemap-image/1.1"
xmlns:video="http://www.google.com/schemas/sitemap-video/1.1">
<url>
<loc>$site-root$</loc>
<changefreq>daily</changefreq>
<priority>1.0</priority>
</url>
$for(pages)$
<url>
<loc>$site-root$$url$</loc>
<lastmod>$if(updated)$$updated$$else$$if(date)$$date$$endif$$endif$</lastmod>
<changefreq>weekly</changefreq>
<priority>0.8</priority>
<changefreq>$if(changefreq)$$changefreq$$else$weekly$endif$</changefreq>
<priority>$if(priority)$$priority$$else$0.8$endif$</priority>
</url>
$endfor$
</urlset>

31
src/Site.hs

@ -1,30 +1,19 @@
module Site (site) where
module Site where
import qualified Data.Text as T
import qualified Data.Text.IO as TIO
import Data.Time
import Site.Common
import Site.Rule
import Site.Rule (rules)
import System.Environment (getEnvironment)
site :: IO ()
site = do
env <- getEnvironment
configIniText <- T.pack <$> readFile "config.ini"
siteConfig <- case parseConfigIni env configIniText of
zonedTime <- getZonedTime
configIniText <- TIO.readFile "config.ini"
siteConfig <- case parseConfigIni env zonedTime configIniText of
Left e -> fail e
Right config -> return $ config & siteContext %~ initContext config
hakyllWith (siteConfig ^. siteHakyllConfiguration) (rules siteConfig)
Right config -> return $ config & siteContext %~ baseContext config
initContext :: SiteConfig -> Context String -> Context String
initContext config context =
constField "body-class" "default"
<> constField "site-root" (config ^. siteRoot)
<> cleanIndexPaths "url"
<> gitCommits (config ^. siteGitWebUrl)
<> imgField
<> includeCodeField
<> youtubeField
<> routeToField
<> commentField
<> siteRootField config
<> demoteHeadersByField
<> context
hakyllWith (siteConfig ^. siteHakyllConfiguration) (rules siteConfig)

14
src/Site/Common.hs

@ -14,12 +14,11 @@ module Site.Common
module Site.Compiler.Layout,
module Site.Compiler.Pandoc,
module Site.Context.Field,
module Site.Context.GitCommits,
module Site.Context.Post,
module Site.Context.Tag,
module Site.Metadata,
module Site.Context,
module Site.Route,
module Site.Util,
module System.Directory,
module System.FilePath,
)
where
@ -37,10 +36,9 @@ import Site.Compiler
import Site.Compiler.Layout
import Site.Compiler.Pandoc
import Site.Config
import Site.Context
import Site.Context.Field
import Site.Context.GitCommits
import Site.Context.Post
import Site.Context.Tag
import Site.Metadata
import Site.Route
import Site.Util
import System.Directory (copyFile, createDirectoryIfMissing, doesFileExist)
import System.FilePath (takeDirectory, (</>))

25
src/Site/Compiler/Layout.hs

@ -28,17 +28,30 @@ instance Binary Layout where
instance Writable Layout where
write p = LBS.writeFile p . B.encode . itemBody
layoutKey :: String
layoutKey = "layout"
layoutScriptsKey :: String
layoutScriptsKey = "scripts"
layoutStylesheetsKey :: String
layoutStylesheetsKey = "stylesheets"
layoutContext :: SimpleGetter Layout (Context String)
layoutContext = to \layout ->
listField "scripts" context (return $ layout ^. layoutScripts)
<> listField "stylesheets" context (return $ layout ^. layoutStylesheets)
listField layoutScriptsKey context (return $ layout ^. layoutScripts)
<> listField layoutStylesheetsKey context (return $ layout ^. layoutStylesheets)
where
context = bodyField "src"
loadLayoutFromMetadata :: Metadata -> Compiler (Maybe (Item Layout))
loadLayoutFromMetadata metadata =
mapM (loadLayout . fromLayoutName) (lookupString layoutKey metadata)
applyLayoutFromMetadata :: SiteConfig -> Item String -> Compiler (Item String)
applyLayoutFromMetadata config item = do
metadata <- getMetadata $ itemIdentifier item
maybeLayout <- sequence (loadLayout . fromLayoutName <$> lookupString "layout" metadata)
maybeLayout <- loadLayoutFromMetadata metadata
let f layout = applyLayout config layout item
maybe (return item) f maybeLayout
@ -57,13 +70,13 @@ layoutCompiler :: Compiler (Item Layout)
layoutCompiler = do
metadata <- getMetadata =<< getUnderlying
template <- makeItem =<< compileTemplateItem =<< getResourceBody
parent <- sequence (loadLayout . fromLayoutName <$> lookupString "layout" metadata)
parent <- loadLayoutFromMetadata metadata
let parentScripts = parentItems layoutScripts parent
scripts = parentScripts ++ toUrlItems (lookupStringList "scripts" metadata)
scripts = parentScripts ++ toUrlItems (lookupStringList layoutScriptsKey metadata)
parentStylesheets = parentItems layoutStylesheets parent
stylesheets = parentStylesheets ++ toUrlItems (lookupStringList "stylesheets" metadata)
stylesheets = parentStylesheets ++ toUrlItems (lookupStringList layoutStylesheetsKey metadata)
parentStack = parentItems layoutStack parent
stack = template : parentStack

9
src/Site/Compiler/Pandoc.hs

@ -1,7 +1,8 @@
module Site.Compiler.Pandoc
( interpolateResourceBody,
( compilePandoc,
compilePandocWith,
interpolateItem,
interpolateResourceBody,
)
where
@ -14,8 +15,8 @@ import Text.Pandoc.Definition
import Text.Pandoc.Highlighting (pygments)
import qualified Text.Pandoc.Options as Opt
compilePandocWithDefault :: Item String -> Compiler (Item String)
compilePandocWithDefault = compilePandocWith return
compilePandoc :: Item String -> Compiler (Item String)
compilePandoc = compilePandocWith return
compilePandocWith :: (Item Pandoc -> Compiler (Item Pandoc)) -> Item String -> Compiler (Item String)
compilePandocWith f =
@ -31,7 +32,7 @@ interpolateResourceBody config =
interpolateItem :: SiteConfig -> Item String -> Compiler (Item String)
interpolateItem config =
applyAsTemplate (config ^. siteContext) . printDebugItem config
>=> compilePandocWithDefault
>=> compilePandoc
readerOpts :: Opt.ReaderOptions
readerOpts =

39
src/Site/Config.hs

@ -5,8 +5,10 @@ import Data.Ini.Config
import Data.Maybe (isJust)
import Data.String (IsString)
import Data.Text (Text)
import Data.Time
import Hakyll
import Hakyll.Core.Configuration as HC
import Lens.Micro
import Lens.Micro.TH
import System.FilePath
@ -16,29 +18,51 @@ data SiteConfig = SiteConfig
_siteTitle :: String,
_siteAuthorName :: String,
_siteAuthorEmail :: String,
_siteLinkedInProfile :: String,
_siteGitWebUrl :: String,
_sitePreview :: Bool,
_siteDebug :: Bool,
_siteHakyllConfiguration :: Configuration,
_siteFeedConfiguration :: FeedConfiguration,
_siteTime :: ZonedTime,
_siteContext :: Context String
}
makeLenses ''SiteConfig
makeHakyllConfigLens :: (Configuration -> a) -> (Configuration -> a -> Configuration) -> Lens' SiteConfig a
makeHakyllConfigLens getter setter = lens getter' setter'
where
getter' siteConfig = getter (siteConfig ^. siteHakyllConfiguration)
setter' siteConfig val = siteConfig & siteHakyllConfiguration %~ flip setter val
siteDestinationDirectory :: Lens' SiteConfig FilePath
siteDestinationDirectory = makeHakyllConfigLens destinationDirectory (\h v -> h {destinationDirectory = v})
siteProviderDirectory :: Lens' SiteConfig FilePath
siteProviderDirectory = makeHakyllConfigLens providerDirectory (\h v -> h {providerDirectory = v})
siteStoreDirectory :: Lens' SiteConfig FilePath
siteStoreDirectory = makeHakyllConfigLens storeDirectory (\h v -> h {storeDirectory = v})
siteInMemoryCache :: Lens' SiteConfig Bool
siteInMemoryCache = makeHakyllConfigLens inMemoryCache (\h v -> h {inMemoryCache = v})
hasEnvFlag :: String -> [(String, String)] -> Bool
hasEnvFlag f e = isJust (lookup f e)
parseConfigIni :: [(String, String)] -> Text -> Either String SiteConfig
parseConfigIni env iniText = parseIniFile iniText do
parseConfigIni :: [(String, String)] -> ZonedTime -> Text -> Either String SiteConfig
parseConfigIni env zonedTime iniText = parseIniFile iniText do
feedDescription <- section "feed" $ fieldOf "description" string
hakyllConfiguration <- section "hakyll" do
destinationDir <- fieldOf "destinationDirectory" string
providerDirectory' <- fieldOf "providerDirectory" string
destinationDirectory' <- fieldOf "destinationDirectory" string
allowedFiles <- fieldOfStrings "allowedFiles"
return
HC.defaultConfiguration
{ destinationDirectory = destinationDir,
{ providerDirectory = providerDirectory',
destinationDirectory = destinationDirectory',
ignoreFile = customIgnoreFile allowedFiles
}
@ -47,8 +71,9 @@ parseConfigIni env iniText = parseIniFile iniText do
title <- fieldOf "title" string
authorName <- fieldOf "authorName" string
authorEmail <- fieldOf "authorEmail" string
preview <- fieldDefOf "preview" flag False <|> pure (hasEnvFlag "SITE_PREVIEW" env)
debug <- fieldDefOf "debug" flag False <|> pure (hasEnvFlag "SITE_DEBUG" env)
linkedInProfile <- fieldOf "linkedInProfile" string
preview <- fieldDefOf "preview" flag False <|> return (hasEnvFlag "SITE_PREVIEW" env)
debug <- fieldDefOf "debug" flag False <|> return (hasEnvFlag "SITE_DEBUG" env)
gitWebUrl <- fieldOf "gitWebUrl" string
return
SiteConfig
@ -57,6 +82,7 @@ parseConfigIni env iniText = parseIniFile iniText do
_siteTitle = title,
_siteAuthorName = authorName,
_siteAuthorEmail = authorEmail,
_siteLinkedInProfile = linkedInProfile,
_siteGitWebUrl = gitWebUrl,
_sitePreview = preview,
_siteDebug = debug,
@ -69,6 +95,7 @@ parseConfigIni env iniText = parseIniFile iniText do
feedAuthorEmail = authorEmail,
feedRoot = root
},
_siteTime = zonedTime,
_siteContext = defaultContext
}
where

32
src/Site/Context.hs

@ -0,0 +1,32 @@
module Site.Context
( module Site.Context.Field,
module Site.Context.GitCommits,
module Site.Context.Post,
module Site.Context.Tag,
baseContext,
)
where
import Hakyll (Context, constField)
import Lens.Micro
import Site.Config
import Site.Context.Field
import Site.Context.GitCommits
import Site.Context.Post
import Site.Context.Tag
baseContext :: SiteConfig -> Context String -> Context String
baseContext config defaultContext =
constField "body-class" "default"
<> constField "site-root" (config ^. siteRoot)
<> constField "linkedin-profile" (config ^. siteLinkedInProfile)
<> removeIndexUrlField "url"
<> gitCommits (config ^. siteGitWebUrl)
<> imgField
<> includeCodeField
<> youtubeField
<> routeToField
<> commentField
<> siteRootField config
<> demoteHeadersByField
<> defaultContext

9
src/Site/Context/Field.hs

@ -6,6 +6,7 @@ module Site.Context.Field
routeToField,
commentField,
demoteHeadersByField,
removeIndexUrlField,
)
where
@ -14,6 +15,14 @@ import Hakyll hiding (demoteHeaders)
import Lens.Micro
import Site.Config (SiteConfig, siteRoot)
import Site.Util
import System.FilePath (splitFileName, takeDirectory)
removeIndexUrlField :: String -> Context a
removeIndexUrlField key = mapContext transform (urlField key)
where
transform url = case splitFileName url of
(p, "index.html") -> takeDirectory p
_ -> url
siteRootField :: SiteConfig -> Context String
siteRootField config = constField "site-root" (config ^. siteRoot)

14
src/Site/Context/GitCommits.hs

@ -9,12 +9,14 @@ import System.Process
gitCommits :: String -> Context String
gitCommits gitWebUrl =
constField "git-web-url" gitWebUrl
<> field "git-sha1" gitSha1Compiler
<> field "git-message" gitMessageCompiler
<> field "is-changed" isChangedCompiler
<> field "is-generated" isGeneratedCompiler
<> field "git-branch" gitBranchCompiler
mconcat
[ constField "git-web-url" gitWebUrl,
field "git-sha1" gitSha1Compiler,
field "git-message" gitMessageCompiler,
field "is-changed" isChangedCompiler,
field "is-generated" isGeneratedCompiler,
field "git-branch" gitBranchCompiler
]
itemSourcePath :: Item a -> FilePath
itemSourcePath item = toFilePath (itemIdentifier item)

4
src/Site/Context/Post.hs

@ -4,4 +4,6 @@ import Hakyll
postContext :: Context String
postContext =
dateField "date" "%B %e, %Y"
dateField "published" "%B %e, %Y"
<> dateField "created" "%B %e, %Y"
<> dateField "updated" "%B %e, %Y"

9
src/Site/Metadata.hs

@ -1,9 +0,0 @@
module Site.Metadata where
import Hakyll
pageType :: Metadata -> Maybe String
pageType = lookupString "page-type"
isStaticPage :: Metadata -> Bool
isStaticPage = (== Just "static") . pageType

18
src/Site/Route.hs

@ -1,6 +1,7 @@
module Site.Route where
import Data.String.Utils (endswith, join, split)
import Data.List (isSuffixOf)
import Data.String.Utils (join, split)
import Hakyll
appendIndexHtml :: Identifier -> FilePath
@ -9,20 +10,19 @@ appendIndexHtml = join "/" . reverse . indexIt . reverse . split "/" . toFilePat
indexIt [] = []
indexIt a@(x : xs)
| x == "index.html" = a
| endswith ".html" x = (head (split "." x) ++ "/index.html") : xs
| ".html" `isSuffixOf` x = (head (split "." x) ++ "/index.html") : xs
| otherwise = a
indexRoute :: Routes
indexRoute = customRoute appendIndexHtml
pageRoute :: Routes
pageRoute = stripPrefixRoute "^pages/"
metaRoute :: Routes
metaRoute = stripPrefixRoute "^meta/"
htmlPageRoute :: Routes
htmlPageRoute = pageRoute `composeRoutes` setExtension "html" `composeRoutes` indexRoute
pageRoute =
composeRoutesList
[ stripPrefixRoute "^pages/",
setExtension "html",
indexRoute
]
stripPrefixRoute :: String -> Routes
stripPrefixRoute prefix = subPrefixRoute prefix ""

15
src/Site/Rule.hs

@ -3,13 +3,13 @@ module Site.Rule where
import Hakyll
import Site.Compiler.Layout
import Site.Config
import Site.Rule.Archive
import Site.Rule.Blog
import Site.Rule.Feed
import Site.Rule.Js
import Site.Rule.Meta
import Site.Rule.Page
import Site.Rule.Robot
import Site.Rule.Sass
import Site.Rule.Sitemap
rules :: SiteConfig -> Rules ()
rules config = do
@ -17,15 +17,15 @@ rules config = do
imageRules
cssRules
templateRules
jsRules
sassRules
downloadRules
jsRules
sassRules config
pageRules config
robotsTxtRules config
codeDependency <- codeRules
rulesExtraDependencies [codeDependency] do
blogRules config
feedRules config
pageRules config
robotsTxtRules config
archiveRules config
sitemapRules config
@ -67,4 +67,5 @@ cssRules =
templateRules :: Rules ()
templateRules = do
match "layouts/**" $ compile layoutCompiler
match "partials/**" $ compile templateBodyCompiler
match "partials/**" $ compile templateCompiler
match "templates/**" $ compile templateCompiler

25
src/Site/Rule/Archive.hs

@ -1,25 +0,0 @@
module Site.Rule.Archive (archiveRules) where
import Site.Common
import Site.Rule.Blog (loadPublishedPosts)
archiveRules :: SiteConfig -> Rules ()
archiveRules config = do
create ["pages/archives.md"] do
route htmlPageRoute
compile $ archiveCompiler config
archiveContext :: [Item String] -> Context String -> Context String
archiveContext posts siteContext' =
constField "title" "Archives"
<> listField "posts" siteContext' (return posts)
<> siteContext'
archiveCompiler :: SiteConfig -> Compiler (Item String)
archiveCompiler config = do
posts <- recentFirst =<< loadPublishedPosts
let localConfig = config & siteContext %~ archiveContext posts
makeItem ""
>>= interpolateItem localConfig
>>= applyLayoutFromMetadata localConfig
>>= relativizeUrls

75
src/Site/Rule/Blog.hs

@ -10,33 +10,40 @@ blogRules :: SiteConfig -> Rules ()
blogRules config =
let rules =
[ blogIndexRules,
archiveRules,
draftArchiveRules,
publishedPostRules,
draftPostRules,
draftArchiveRules
draftPostRules
]
in sequenceA_ $ rules <*> pure config
blogIndexRules :: SiteConfig -> Rules ()
blogIndexRules config =
match "pages/blog.md" do
route htmlPageRoute
create ["blog/blog.html"] do
route indexRoute
compile $ blogCompiler config
archiveRules :: SiteConfig -> Rules ()
archiveRules config = do
create ["blog/archives.html"] do
route indexRoute
compile $ archiveCompiler config
draftArchiveRules :: SiteConfig -> Rules ()
draftArchiveRules config = do
match "pages/drafts.md" do
route htmlPageRoute
create ["blog/drafts.html"] do
route indexRoute
compile $ draftPostsCompiler config
publishedPostRules :: SiteConfig -> Rules ()
publishedPostRules localConfig = do
matchMetadata "blog/**" isPublished do
matchMetadata "posts/**" isPublished do
route publishedPostRoute
compile $ postCompiler localConfig publishedSnapshot
draftPostRules :: SiteConfig -> Rules ()
draftPostRules localConfig = do
matchMetadata "blog/**" isDraft do
matchMetadata "posts/**" isDraft do
route draftPostRoute
compile $ postCompiler localConfig draftSnapshot
@ -53,38 +60,41 @@ draftSnapshot :: PostSnapshot
draftSnapshot = "_draftPost"
loadPublishedPosts :: Compiler [Item String]
loadPublishedPosts = loadExistingSnapshots "blog/*" publishedSnapshot
loadPublishedPosts = loadExistingSnapshots "posts/**" publishedSnapshot
loadDraftPosts :: Compiler [Item String]
loadDraftPosts = loadExistingSnapshots "blog/*" draftSnapshot
loadDraftPosts = loadExistingSnapshots "posts/**" draftSnapshot
{-----------------------------------------------------------------------------}
{- Routes -}
{-----------------------------------------------------------------------------}
postPattern :: String
postPattern = "^blog/[0-9]{4}-[0-9]{2}-[0-9]{2}-"
datePattern :: String
datePattern = "[0-9]{4}-[0-9]{2}-[0-9]{2}-"
matchPostRoute :: Routes -> Routes
matchPostRoute = matchRoute (fromRegex postPattern)
postPattern :: String
postPattern = "^posts/([^/]+/)?" ++ datePattern
publishedPostRoute :: Routes
publishedPostRoute =
matchPostRoute . composeRoutesList $
basePostRoute :: Routes
basePostRoute =
matchRoute (fromRegex postPattern) . composeRoutesList $
[ dateRoute,
setExtension "html",
indexRoute
]
publishedPostRoute :: Routes
publishedPostRoute = basePostRoute `composeRoutes` postDestination "blog/"
draftPostRoute :: Routes
draftPostRoute =
matchPostRoute . composeRoutesList $
[ publishedPostRoute,
gsubRoute "^blog/" (replaceAll "^blog/" (const "drafts/"))
]
draftPostRoute = basePostRoute `composeRoutes` postDestination "blog/drafts/"
postDestination :: String -> Routes
postDestination destinationDir =
gsubRoute "^posts/" (replaceAll "^posts/" (const destinationDir))
dateRoute :: Routes
dateRoute = gsubRoute postPattern (replaceAll "-" (const "/"))
dateRoute = gsubRoute datePattern (replaceAll "-" (const "/"))
{-----------------------------------------------------------------------------}
{- Compilers -}
@ -109,8 +119,8 @@ blogCompiler config = do
-- set local config
let localConfig = config & siteContext %~ blogContext latestPost otherPosts
interpolateResourceBody localConfig
>>= applyLayoutFromMetadata config
makeItem ""
>>= applyLayoutFromMetadata localConfig
>>= relativizeUrls
draftPostsCompiler :: SiteConfig -> Compiler (Item String)
@ -118,7 +128,14 @@ draftPostsCompiler config = do
posts <- recentFirst =<< loadDraftPosts
let localConfig = config & siteContext %~ (draftArchiveContext config posts <>)
makeItem ""
>>= interpolateItem localConfig
>>= applyLayoutFromMetadata localConfig
>>= relativizeUrls
archiveCompiler :: SiteConfig -> Compiler (Item String)
archiveCompiler config = do
posts <- recentFirst =<< loadPublishedPosts
let localConfig = config & siteContext %~ archiveContext posts
makeItem ""
>>= applyLayoutFromMetadata localConfig
>>= relativizeUrls
@ -140,6 +157,12 @@ blogContext latestPost otherPosts siteContext' = do
(return otherPosts)
<> siteContext'
archiveContext :: [Item String] -> Context String -> Context String
archiveContext posts siteContext' =
constField "title" "Archives"
<> listField "posts" siteContext' (return posts)
<> siteContext'
{-----------------------------------------------------------------------------}
{- Metadata -}
{-----------------------------------------------------------------------------}

25
src/Site/Rule/Meta.hs

@ -1,25 +0,0 @@
module Site.Rule.Meta where
import Site.Common
import Site.Rule.Blog (loadPublishedPosts)
robotsTxtRules :: SiteConfig -> Rules ()
robotsTxtRules config = do
match "meta/robots.txt" do
route metaRoute
compile $ applyAsTemplate (config ^. siteContext) =<< getResourceBody
sitemapRules :: SiteConfig -> Rules ()
sitemapRules config =
match "meta/sitemap.xml" $ do
route metaRoute
compile $ sitemapCompiler config
sitemapCompiler :: SiteConfig -> Compiler (Item String)
sitemapCompiler config = do
posts <- recentFirst =<< loadPublishedPosts
pages <- loadAll "pages/**"
let pageField = listField "pages" (config ^. siteContext) (return $ posts <> pages)
localConfig = config & siteContext %~ (pageField <>)
makeItem ""
>>= applyAsTemplate (localConfig ^. siteContext)

4
src/Site/Rule/Page.hs

@ -4,8 +4,8 @@ import Site.Common
pageRules :: SiteConfig -> Rules ()
pageRules config = do
matchMetadata "pages/**" isStaticPage do
route htmlPageRoute
match "pages/**" do
route pageRoute
compile $
interpolateResourceBody config
>>= applyLayoutFromMetadata config

16
src/Site/Rule/Robot.hs

@ -0,0 +1,16 @@
module Site.Rule.Robot where
import Site.Common
robotsTxtRules :: SiteConfig -> Rules ()
robotsTxtRules config = do
create ["robots.txt"] do
route idRoute
compile $ robotsTxtCompiler config
robotsTxtCompiler :: SiteConfig -> Compiler (Item String)
robotsTxtCompiler config = do
makeItem ""
>>= loadAndApplyTemplate
(fromFilePath "templates/robots.txt")
(config ^. siteContext)

20
src/Site/Rule/Sass.hs

</
@ -2,16 +2,20 @@ module Site.Rule.Sass (sassRules) where
import Site.Common
sassRules :: Rules ()
sassRules = do
sassDependency <- makePatternDependency "css/**.sass"