nav.scm 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120
  1. (library (templates nav)
  2. (export nav-template)
  3. (import
  4. (except (rnrs base) let-values error)
  5. (only (guile)
  6. lambda* λ
  7. simple-format
  8. current-output-port)
  9. ;; exception handling
  10. (ice-9 exceptions)
  11. (prefix (srfi srfi-1) srfi-1:)
  12. ;; for functional structs (not part of srfi-9 directly)
  13. (srfi srfi-9 gnu)
  14. ;; standard web library
  15. (web request)
  16. (web response)
  17. (web uri)
  18. ;; web location
  19. (lib web-location-handling)
  20. (lib utils request-utils)
  21. (lib utils url-utils)))
  22. (define-immutable-record-type <nav-link>
  23. ;; define constructor
  24. (construct-nav-link label slugs)
  25. ;; define predicate
  26. nav-link?
  27. ;; define accessors and functional setters
  28. (label nav-link-label)
  29. (slugs nav-link-slugs))
  30. (define make-nav-link
  31. (λ (label slugs)
  32. (cond
  33. [(not (string? label))
  34. (raise-exception
  35. (make-exception
  36. (make-non-continuable-error)
  37. (make-exception-with-message "nav link label not given as string")
  38. (make-exception-with-irritants (list label))
  39. (make-exception-with-origin 'make-nav-link)))]
  40. [(not (list? slugs))
  41. (raise-exception
  42. (make-exception
  43. (make-non-continuable-error)
  44. (make-exception-with-message "nav link slugs not given as list")
  45. (make-exception-with-irritants (list slugs))
  46. (make-exception-with-origin 'make-nav-link)))]
  47. [else (construct-nav-link label slugs)])))
  48. (define nav-link-main-ref
  49. (λ (nav-link)
  50. (srfi-1:first (nav-link-slugs nav-link))))
  51. (define nav-links
  52. (list (make-nav-link "Home" '("/" "/home"))
  53. (make-nav-link "Schedule" '("/schedule"))
  54. (make-nav-link "Resources" '("/resources"))
  55. (make-nav-link "About" '("/about"))))
  56. (define nav-logo-template
  57. (λ (request body)
  58. `(div (@ (class "dd-nav-logo"))
  59. #;(img (@ (src ,(static-asset-location '("img" "logo" "dragon-descendants-logo.png"))))))))
  60. (define nav-link-template
  61. (lambda* (label reference #:key (active #f))
  62. `(li (@ (class ,(if active "active" "inactive")))
  63. (a (@ (href ,reference))
  64. (span ,label)))))
  65. (define nav-link-active?
  66. (λ (request nav-link)
  67. "Check whether the slug of the request matches any associated slug of the
  68. navigation link, to determin, whether the navigation link is the active link."
  69. (let ([req-path-comps (request-path-components request)]
  70. [link-slugs (nav-link-slugs nav-link)])
  71. ;; fold over all associated slugs of the link to check if any one is
  72. ;; matching the currently requested route
  73. (srfi-1:fold
  74. ;; proc
  75. (λ (link-slug acc)
  76. (or (equal? req-path-comps (url-slug-components link-slug))
  77. acc))
  78. ;; init
  79. #f
  80. ;; list
  81. link-slugs))))
  82. (define nav-links-template
  83. (λ (request body)
  84. ;; render single links
  85. (map (λ (nav-link)
  86. (nav-link-template (nav-link-label nav-link)
  87. (nav-link-main-ref nav-link)
  88. #:active (nav-link-active? request nav-link)))
  89. nav-links)))
  90. (define nav-template
  91. (λ (request body)
  92. `((nav (@ (class "nav nav-outer-cluster"))
  93. ;; the outer cluster contains a list of the logo and the inner cluster
  94. (ul
  95. (li
  96. ,(nav-logo-template request body))
  97. (li
  98. (div (@ (class "nav-menu nav-inner-cluster"))
  99. ;; the inner cluster contains the navigation menu items
  100. (ul
  101. ,@(nav-links-template request body)))))))))