2024-03-07 18:13:23 +01:00
;; Variables
( defvar domain " django-liveview.andros.dev " )
2024-03-06 09:24:25 +01:00
;; Utils
2024-02-29 13:03:14 +01:00
( defun make-title ( title )
2024-02-29 18:41:29 +01:00
" If title is empty, return the website name. Otherwise, return the title with the website name. "
2024-02-29 13:03:14 +01:00
( concat ( when ( not ( string-empty-p title ) ) ( concat title " | " ) ) " Django LiveView " ) )
2024-03-06 09:24:25 +01:00
( defun one-ox-link ( link desc info )
" Transcode a LINK object from Org to HTML.
DESC is the description part of the link, or the empty string.
INFO is a plist holding contextual information. "
( let* ( ( type ( org-element-property :type link ) )
( path ( org-element-property :path link ) )
( raw-link ( org-element-property :raw-link link ) )
( custom-type-link
( let ( ( export-func ( org-link-get-parameter type :export ) ) )
( and ( functionp export-func )
( funcall export-func path desc 'one-ox info ) ) ) )
( href ( cond
( ( string= type " custom-id " ) path )
( ( string= type " fuzzy " )
( let ( ( beg ( org-element-property :begin link ) ) )
( signal 'one-link-broken
` ( , raw-link
" fuzzy links not supported "
, ( format " goto-char: %s " beg ) ) ) ) )
( ( string= type " file " )
( or
;; ./assets/images/image-1.png --> /images/image-1.png
;; ./public/blog/page-1.md --> /blog/page-1.md
( and ( string-match " \\ ` \\ ./ \\ (assets \\ |public \\ ) " path )
( replace-match " " nil nil path ) )
( let ( ( beg ( org-element-property :begin link ) ) )
( signal 'one-link-broken
` ( , raw-link , ( format " goto-char: %s " beg ) ) ) ) ) )
( t raw-link ) ) )
( class ( if-let ( ( parent ( org-export-get-parent-element link ) )
( class ( plist-get ( org-export-read-attribute :attr_html parent )
:class ) ) )
( concat " class= \" " class " \" " )
" " ) ) )
( or custom-type-link
( and
( string-match one-ox-link-image-extensions path )
( format " <p><img%ssrc= \" %s \" alt= \" %s \" /></p> "
class href ( or ( org-string-nw-p desc ) href ) ) )
( format " <a%shref= \" %s \" >%s</a> "
class href ( or ( org-string-nw-p desc ) href ) ) ) ) )
;; Layouts
2024-02-29 13:03:14 +01:00
( defun render-layout-html ( title description tree-content )
2024-02-29 18:41:29 +01:00
" Render the HTML layout with the given title, description and content. "
( let ( ( full-title ( make-title title ) ) )
( jack-html
" <!DOCTYPE html> "
` ( :html ( @ :lang " en " )
( :head
2024-03-12 09:52:49 +01:00
;; Yandex.Metrika counter
( :script ( @ :type " text/javascript " ) " (function(m,e,t,r,i,k,a){m[i]=m[i]||function(){(m[i].a=m[i].a||[]).push(arguments)};
m [ i ] . l=1*new Date ( ) ;
for ( var j = 0 ; j < document.scripts.length; j++) {if (document.scripts[j].src === r) { return; }}
k=e.createElement ( t ) , a=e.getElementsByTagName ( t ) [ 0 ] , k.async=1,k.src=r,a.parentNode.insertBefore ( k,a ) } )
( window, document, 'script ', 'https://mc.yandex.ru/metrika/tag.js ', 'ym ' ) ;
ym ( 95556716 , 'init ', {
clickmap:true,
trackLinks:true,
accurateTrackBounce:true,
webvisor:true
} ) ;")
( :noscript
( :div ( :img ( @ :src " https://mc.yandex.ru/watch/95556716 " :style " position:absolute; left:-9999px; " :alt " " ) ) ) )
2024-02-29 18:41:29 +01:00
;; Generals
( :meta ( @ :charset " utf-8 " ) )
( :link ( @ :rel " icon " :type " image/png " :href " /img/favicon.png " ) )
( :meta ( @ :name " viewport " :content " width=device-width,initial-scale=1.0, shrink-to-fit=no " ) )
( :meta ( @ :name " author " :content " Andros Fenollosa " ) )
( :meta ( @ :name " generator " :content " One.el " ) )
;; SEO
( :title , full-title )
( :meta ( @ :name " description " :content , description ) )
( :meta ( @ :name " og:image " :content " https://django-liveview.andros.dev/img/og-image.webp " ) )
;; Fonts
( :link ( @ :rel " preconnect " :href " https://fonts.googleapis.com " ) )
( :link ( @ :rel " preconnect " :href " https://fonts.gstatic.com " :crossorigin t ) )
( :link ( @ :rel " stylesheet " :href " https://fonts.googleapis.com/css2?family=Fira+Code&family=Open+Sans:wght@400;700&display=swap " ) )
;; CSS
( :link ( @ :rel " stylesheet " :type " text/css " :href " https://cdnjs.cloudflare.com/ajax/libs/normalize/8.0.1/normalize.min.css " ) )
2024-03-14 11:06:54 +01:00
( :link ( @ :rel " stylesheet " :type " text/css " :href , ( concat " /css/main.css?cache= " ( format-time-string " %s " ) ) ) ) )
2024-02-29 18:41:29 +01:00
( :body
( :header.header
( :div.container
( :nav.nav-main
( :ul.nav__list.nav-main__list
( :li.nav-main__item
( :a.nav-main__link.nav-main__link--logo ( @ :href " / " ) ( :img.nav-main__logo ( @ :alt " Django LiveView " :src " /img/logo.webp " ) ) ) )
( :li.nav-main__item
2024-03-14 11:02:04 +01:00
( :a.button.nav-main__link ( @ :href " /docs/install/ " ) " Docs " ) )
2024-02-29 18:41:29 +01:00
( :li.nav-main__item
2024-03-14 11:02:04 +01:00
( :a.button.nav-main__link ( @ :href " /tutorials/ " ) " Tutorials " ) )
2024-02-29 18:41:29 +01:00
( :li.nav-main__item
2024-03-10 20:15:03 +01:00
( :a.button.nav-main__link ( @ :href " https://django-liveview-demo.andros.dev/ " :target " _blank " ) " Demo " ) )
( :li.nav-main__item
2024-03-14 11:02:04 +01:00
( :a.button.nav-main__link ( @ :href " /books/ " ) " Books " ) )
( :li.nav-main__item
( :a.button.nav-main__link ( @ :href " /source-code/ " ) " Source code " ) ) ) ) ) )
2024-02-29 18:41:29 +01:00
, tree-content
( :footer.footer
2024-03-08 09:36:13 +01:00
( :p " Created with " ( :i ( @ :aria-label " love " ) " ❤️ " ) " by " ( :a.link ( @ :href " https://andros.dev/ " :target " _blank " ) " Andros Fenollosa " ) " with " ( :a.link ( @ :href " https://one.tonyaldon.com/ " :target " _blank " ) " one.el " ) )
( :p ( :a.link ( @ :href " https://github.com/Django-LiveView/docs/blob/main/one.org " :target " _blank " ) " I have seen a " ( :i ( @ :aria-label " bug " ) " 🪲 " ) " in the documentation " ) )
2024-02-29 18:41:29 +01:00
( :p " 🐍 " , ( format-time-string " %Y " ) ) ) ) ) ) ) )
2024-02-29 13:03:14 +01:00
2024-03-01 09:00:24 +01:00
( defun one-custom-default-page ( page-tree pages _global )
" Default render function by home page. "
( let* ( ( title ( org-element-property :raw-value page-tree ) )
( description ( org-element-property :DESCRIPTION page-tree ) )
( path ( org-element-property :CUSTOM_ID page-tree ) )
( content ( org-export-data-with-backend
( org-element-contents page-tree )
'one-ox nil ) )
( website-name ( one-default-website-name pages ) )
( nav ( one-default-nav path pages ) ) )
( render-layout-html
title
description
( jack-html ` ( :main.main
( :section
( :div.container , content ) ) ) ) ) ) )
2024-02-28 18:49:12 +01:00
( defun one-custom-default-home ( page-tree pages _global )
" Default render function by home page. "
( let* ( ( title ( org-element-property :TITLE page-tree ) )
( path ( org-element-property :CUSTOM_ID page-tree ) )
( description ( org-element-property :DESCRIPTION page-tree ) )
( content ( org-export-data-with-backend
( org-element-contents page-tree )
'one-ox nil ) )
( website-name ( one-default-website-name pages ) )
( nav ( one-default-nav path pages ) ) )
2024-02-29 13:03:14 +01:00
( render-layout-html
title
description
( jack-html ` ( :main.main
2024-03-01 09:00:24 +01:00
( :section.hero
( :div.container
( :hgroup.hero__hgroup
( :h1.hero__title " Django LiveView " )
( :h2.hero__subtitle " Framework for creating Realtime SPAs using HTML over the Wire technology " )
( :img.image.hero__logo ( @ :alt " pet " :src " img/pet.webp " ) ) ) ) )
2024-03-04 15:36:50 +01:00
( :section.home
2024-03-01 09:00:24 +01:00
( :div.container , content ) ) ) ) ) ) )
2024-02-28 18:49:12 +01:00
( defun one-custom-default-doc ( page-tree pages _global )
" Default render function by home page. "
2024-02-28 13:12:16 +01:00
( let* ( ( title ( org-element-property :raw-value page-tree ) )
2024-02-29 13:03:14 +01:00
( description ( org-element-property :DESCRIPTION page-tree ) )
2024-02-28 18:49:12 +01:00
( path ( org-element-property :CUSTOM_ID page-tree ) )
2024-02-28 13:12:16 +01:00
( content ( org-export-data-with-backend
( org-element-contents page-tree )
'one-ox nil ) )
( website-name ( one-default-website-name pages ) )
( nav ( one-default-nav path pages ) ) )
2024-02-29 17:08:43 +01:00
( render-layout-html
2024-02-29 13:03:14 +01:00
title
description
2024-03-01 09:00:24 +01:00
( jack-html ` ( :div.container.docs
( :aside.aside-docs
( :nav.nav-docs
( :ul.nav__list.nav__list--docs.nav-docs__list
( :li.nav-docs__item
2024-03-14 11:02:04 +01:00
( :a.nav-docs__link ( @ :href " /docs/install/ " ) " Install " ) )
2024-03-08 09:36:13 +01:00
( :li.nav-docs__item
( :a.nav-docs__link ( @ :href " /docs/actions/ " ) " Actions " ) )
2024-03-05 09:42:05 +01:00
( :li.nav-docs__item
( :a.nav-docs__link ( @ :href " /docs/views/ " ) " Views " ) )
2024-03-07 11:32:08 +01:00
( :li.nav-docs__item
( :a.nav-docs__link ( @ :href " /docs/routing/ " ) " Routing " ) )
2024-03-08 09:36:13 +01:00
( :li.nav-docs__item
( :a.nav-docs__link ( @ :href " /docs/history/ " ) " History " ) )
2024-03-14 11:02:04 +01:00
( :li.nav-docs__item
( :a.nav-docs__link ( @ :href " /docs/internationalization/ " ) " Internationalization " ) )
2024-03-03 09:43:13 +01:00
( :li.nav-docs__item
( :a.nav-docs__link ( @ :href " /docs/deploy/ " ) " Deploy " ) )
2024-03-01 09:00:24 +01:00
( :li.nav-docs__item
( :a.nav-docs__link ( @ :href " /docs/faq/ " ) " FAQ " ) )
2024-03-01 09:20:05 +01:00
) ) )
2024-03-01 09:03:44 +01:00
( :main.main.main--docs
2024-03-01 09:00:24 +01:00
, content ) ) ) ) ) )
2024-03-07 18:13:23 +01:00
2024-03-14 11:02:04 +01:00
( defun one-custom-default-tutorials ( page-tree pages _global )
" Default render function by tutorials page. "
( let* ( ( title ( org-element-property :raw-value page-tree ) )
( description ( org-element-property :DESCRIPTION page-tree ) )
( path ( org-element-property :CUSTOM_ID page-tree ) )
( content ( org-export-data-with-backend
( org-element-contents page-tree )
'one-ox nil ) )
( website-name ( one-default-website-name pages ) )
( nav ( one-default-nav path pages ) ) )
( render-layout-html
title
description
( jack-html ` ( :main.main
( :section.tutorials
( :div.container , content ) ) ) ) ) ) )
2024-03-07 18:13:23 +01:00
;; Sitemap
( defun make-sitemap ( pages tree global )
" Produce file ./public/sitemap.txt "
( with-temp-file " ./public/sitemap.txt "
( insert
( mapconcat 'identity ( mapcar
( lambda ( page )
( let* ( ( path ( plist-get page :one-path ) )
( link ( concat " https:// " domain path ) ) )
link
) )
pages ) " \n " ) ) ) )
( add-hook 'one-hook 'make-sitemap )