Better website

This commit is contained in:
Andros Fenollosa 2024-03-29 22:56:25 +01:00
parent 1b1e4627fa
commit 9fdaa8ccca
3 changed files with 64 additions and 28 deletions

View File

@ -86,27 +86,6 @@ a:hover,
list-style-type: var(--arrow); list-style-type: var(--arrow);
} }
.nav-main__list {
grid-gap: 1rem;
}
@media (width < 600px) {
.nav-main__list > li:first-child {
margin-right: 6rem;
}
}
.nav-main__logo {
width: 80px;
margin-bottom: calc(var(--gap-m) * -1);
}
.nav-main__link--logo {
padding-bottom: 0;
position: absolute;
bottom: 0;
}
.center-block { .center-block {
display: block; display: block;
margin-inline: auto; margin-inline: auto;
@ -189,6 +168,37 @@ a:hover,
} }
} }
.nav-main__list {
grid-gap: 1rem;
}
@media (width < 600px) {
.nav-main__list > li:first-child {
margin-right: 6rem;
}
}
.nav-main__logo {
width: 80px;
margin-bottom: calc(var(--gap-m) * -1);
}
.nav-main__link--logo {
padding-bottom: 0;
position: absolute;
bottom: 0;
}
.nav-main--active {
background-color: var(--color-brown);
color: var(--color-black);
}
.nav-main--active:hover {
transform: initial;
box-shadow: initial;
}
.nav__list { .nav__list {
display: flex; display: flex;
flex-wrap: wrap; flex-wrap: wrap;

17
one.org
View File

@ -4,6 +4,7 @@
:CUSTOM_ID: / :CUSTOM_ID: /
:TITLE: :TITLE:
:DESCRIPTION: Framework for creating Realtime SPAs using HTML over the Wire technology. :DESCRIPTION: Framework for creating Realtime SPAs using HTML over the Wire technology.
:NAVIGATOR-ACTIVE: home
:END: :END:
** What is HTML over the Wire? ** What is HTML over the Wire?
@ -64,6 +65,7 @@ Are you ready to create your first Realtime SPA? Let's go to the [[#/tutorials/q
:CUSTOM_ID: /docs/install/ :CUSTOM_ID: /docs/install/
:TITLE: Install :TITLE: Install
:DESCRIPTION: Install Django LiveView. :DESCRIPTION: Install Django LiveView.
:NAVIGATOR-ACTIVE: docs
:END: :END:
You can install Django LiveView with ~pip~. You can install Django LiveView with ~pip~.
@ -104,6 +106,7 @@ We strongly recommend that you follow the [[#/tutorials/quickstart/][Quickstart]
:CUSTOM_ID: /docs/actions/ :CUSTOM_ID: /docs/actions/
:TITLE: Actions :TITLE: Actions
:DESCRIPTION: Actions of Django LiveView. :DESCRIPTION: Actions of Django LiveView.
:NAVIGATOR-ACTIVE: docs
:END: :END:
Actions are where business logic is stored. The place where you write the functions in Python instead of JavaScript. They are the ones that will be executed when the page is loaded, when a button is clicked, when a form is submitted, etc. The can be launched by the backend or by the frontend. For example, when a button is clicked, the frontend sends a request to the backend to execute an action. But the backend can send a request to the frontend at any time, for example when a new commentary is added to an article then all clients will receive the new commentary. In other words, the actions can be executed by the backend or by the frontend. The more common actions will be render HTML and send it to the client, but you can do anything you want. They are the heart of Django LiveView. Actions are where business logic is stored. The place where you write the functions in Python instead of JavaScript. They are the ones that will be executed when the page is loaded, when a button is clicked, when a form is submitted, etc. The can be launched by the backend or by the frontend. For example, when a button is clicked, the frontend sends a request to the backend to execute an action. But the backend can send a request to the frontend at any time, for example when a new commentary is added to an article then all clients will receive the new commentary. In other words, the actions can be executed by the backend or by the frontend. The more common actions will be render HTML and send it to the client, but you can do anything you want. They are the heart of Django LiveView.
@ -353,6 +356,7 @@ It would be equivalent to doing:
:CUSTOM_ID: /docs/views/ :CUSTOM_ID: /docs/views/
:TITLE: Views :TITLE: Views
:DESCRIPTION: Views of Django LiveView. :DESCRIPTION: Views of Django LiveView.
:NAVIGATOR-ACTIVE: docs
:END: :END:
Django LiveView uses the same views as Django, but the main difference is that the views are asynchronous by default. Django LiveView uses the same views as Django, but the main difference is that the views are asynchronous by default.
@ -397,6 +401,7 @@ Or transform ~articles~ to a list. But you lose the benefits of ORM.
:CUSTOM_ID: /docs/routing/ :CUSTOM_ID: /docs/routing/
:TITLE: Routing :TITLE: Routing
:DESCRIPTION: Routing of Django LiveView. :DESCRIPTION: Routing of Django LiveView.
:NAVIGATOR-ACTIVE: docs
:END: :END:
If you want to move from one page to another, you can use the ~page~ controller and the ~changePage~ action. If you want to move from one page to another, you can use the ~page~ controller and the ~changePage~ action.
@ -478,6 +483,7 @@ Here you can see a typical example of a single page of a blog.
:CUSTOM_ID: /docs/forms/ :CUSTOM_ID: /docs/forms/
:TITLE: Forms :TITLE: Forms
:DESCRIPTION: Forms of Django LiveView. :DESCRIPTION: Forms of Django LiveView.
:NAVIGATOR-ACTIVE: docs
:END: :END:
Los formularios en Django LiveView son nativos de Django. Puedes usar los formularios de modelo, los formularios de clase, los formularios de funciones, etc. O crearlos directamente en HTML. La única diferencia es que los datos se envían a través de WebSockets en lugar de HTTP. Los formularios en Django LiveView son nativos de Django. Puedes usar los formularios de modelo, los formularios de clase, los formularios de funciones, etc. O crearlos directamente en HTML. La única diferencia es que los datos se envían a través de WebSockets en lugar de HTTP.
@ -613,6 +619,7 @@ Para validar un formulario puedes hacerlo de la misma forma que en Django. Pero
:CUSTOM_ID: /docs/history/ :CUSTOM_ID: /docs/history/
:TITLE: History :TITLE: History
:DESCRIPTION: History management of Django LiveView. :DESCRIPTION: History management of Django LiveView.
:NAVIGATOR-ACTIVE: docs
:END: :END:
If you make a SPA you will have a problem with the history management system. When you go back in history, you will lose the data and the HTML of the previous page. This is because the data is removed from the DOM. It is not a problem with Django LiveView. If you make a SPA you will have a problem with the history management system. When you go back in history, you will lose the data and the HTML of the previous page. This is because the data is removed from the DOM. It is not a problem with Django LiveView.
@ -631,6 +638,7 @@ If you want to disable it, remove `startHistory();` from ~assets/js/main.js~.
:CUSTOM_ID: /docs/internationalization/ :CUSTOM_ID: /docs/internationalization/
:TITLE: Internationalization :TITLE: Internationalization
:DESCRIPTION: Internationalization of Django LiveView. :DESCRIPTION: Internationalization of Django LiveView.
:NAVIGATOR-ACTIVE: docs
:END: :END:
Django LiveView uses the same internationalization system as Django. You can read more about it in the [[https://docs.djangoproject.com/en/dev/topics/i18n/][Django documentation]]. However, let's go deeper. Django LiveView uses the same internationalization system as Django. You can read more about it in the [[https://docs.djangoproject.com/en/dev/topics/i18n/][Django documentation]]. However, let's go deeper.
@ -679,6 +687,7 @@ You can read the tutorial [[#/tutorials/internationalize-with-subdomains/][Inter
:CUSTOM_ID: /docs/loading/ :CUSTOM_ID: /docs/loading/
:TITLE: Loading :TITLE: Loading
:DESCRIPTION: Loading management of Django LiveView. :DESCRIPTION: Loading management of Django LiveView.
:NAVIGATOR-ACTIVE: docs
:END: :END:
It is very useful when the database access is slow or you access external services like APIs. You can make a loading animation while the page is being rendered. It is very useful when the database access is slow or you access external services like APIs. You can make a loading animation while the page is being rendered.
@ -762,6 +771,7 @@ This will render the loading HTML in ~#loading~ before running the action and cl
:CUSTOM_ID: /docs/lost-connection/ :CUSTOM_ID: /docs/lost-connection/
:TITLE: Lost connection :TITLE: Lost connection
:DESCRIPTION: Lost connection management of Django LiveView. :DESCRIPTION: Lost connection management of Django LiveView.
:NAVIGATOR-ACTIVE: docs
:END: :END:
It may be the case that the connection is lost, when user has lost the internet connection or the server has been restarted, and it's a problem because Django LiveView depends on a constant connection. In these cases, the client automatically will try to reconnect to the server. But while this happens, the user will have to be informed and any type of interaction blocked. If you do not block user interactions, actions will accumulate in the browser until communication is reestablished. Where they will all be sent at once. If, for example, the user impatiently presses the next page button 10 times, the user will skip 10 pages. It is a problem for him and for the server that will process many instructions at once. It may be the case that the connection is lost, when user has lost the internet connection or the server has been restarted, and it's a problem because Django LiveView depends on a constant connection. In these cases, the client automatically will try to reconnect to the server. But while this happens, the user will have to be informed and any type of interaction blocked. If you do not block user interactions, actions will accumulate in the browser until communication is reestablished. Where they will all be sent at once. If, for example, the user impatiently presses the next page button 10 times, the user will skip 10 pages. It is a problem for him and for the server that will process many instructions at once.
@ -803,6 +813,7 @@ If there is no connection, the ~#no-connection~ will be displayed with ~.no-conn
:CUSTOM_ID: /docs/deploy/ :CUSTOM_ID: /docs/deploy/
:TITLE: Deploy :TITLE: Deploy
:DESCRIPTION: Deploy Django LiveView to production. :DESCRIPTION: Deploy Django LiveView to production.
:NAVIGATOR-ACTIVE: docs
:END: :END:
You can deploy Django LiveView using any web server like reverse proxy. You can deploy Django LiveView using any web server like reverse proxy.
@ -849,6 +860,7 @@ It is important to note that the ~proxy_set_header~ lines are necessary for the
:CUSTOM_ID: /docs/faq/ :CUSTOM_ID: /docs/faq/
:TITLE: FAQ (Frequently Asked Questions) :TITLE: FAQ (Frequently Asked Questions)
:DESCRIPTION: Frequently asked questions about Django LiveView. :DESCRIPTION: Frequently asked questions about Django LiveView.
:NAVIGATOR-ACTIVE: docs
:END: :END:
** Do I need to know JavaScript to use Django LiveView? ** Do I need to know JavaScript to use Django LiveView?
@ -882,6 +894,7 @@ Only me and my free time. If you want to support the project, you can be my [[ht
:CUSTOM_ID: /tutorials/ :CUSTOM_ID: /tutorials/
:TITLE: Tutorials :TITLE: Tutorials
:DESCRIPTION: Tutorials about Django LiveView. :DESCRIPTION: Tutorials about Django LiveView.
:NAVIGATOR-ACTIVE: tutorials
:END: :END:
** Tutorials ** Tutorials
@ -897,6 +910,7 @@ Learn how to create a Django LiveView application step by step.
:CUSTOM_ID: /tutorials/quickstart/ :CUSTOM_ID: /tutorials/quickstart/
:TITLE: Quickstart :TITLE: Quickstart
:DESCRIPTION: Get started with Django LiveView the easy way. :DESCRIPTION: Get started with Django LiveView the easy way.
:NAVIGATOR-ACTIVE: tutorials
:END: :END:
Welcome to the Quickstart guide. Here you will learn how to create your first Realtime SPA using Django LiveView. I assume you have a basic understanding of Django and Python. Welcome to the Quickstart guide. Here you will learn how to create your first Realtime SPA using Django LiveView. I assume you have a basic understanding of Django and Python.
@ -1190,6 +1204,7 @@ The next step is to create a more complex application. You can read other [[#/tu
:CUSTOM_ID: /tutorials/internationalize-with-subdomains/ :CUSTOM_ID: /tutorials/internationalize-with-subdomains/
:TITLE: Internationalize with subdomains :TITLE: Internationalize with subdomains
:DESCRIPTION: Create a multilingual website with subdomains. :DESCRIPTION: Create a multilingual website with subdomains.
:NAVIGATOR-ACTIVE: tutorials
:END: :END:
Here you will learn how to create a multilingual website using Django LiveView. Here you will learn how to create a multilingual website using Django LiveView.
@ -1411,6 +1426,7 @@ Or also simple links with the subdomain.
:CUSTOM_ID: /source-code/ :CUSTOM_ID: /source-code/
:TITLE: Source code :TITLE: Source code
:DESCRIPTION: List of all related source code. :DESCRIPTION: List of all related source code.
:NAVIGATOR-ACTIVE: source code
:END: :END:
You can find all the source code in the following repositories: You can find all the source code in the following repositories:
@ -1430,6 +1446,7 @@ You can find all the source code in the following repositories:
:CUSTOM_ID: /books/ :CUSTOM_ID: /books/
:TITLE: :TITLE:
:DESCRIPTION: Books about Django LiveView. :DESCRIPTION: Books about Django LiveView.
:NAVIGATOR-ACTIVE: books
:END: :END:
There are no books about Django LiveView yet. But you can find book about Django working with HTML over the Wire technology. There are no books about Django LiveView yet. But you can find book about Django working with HTML over the Wire technology.

View File

@ -50,9 +50,10 @@
;; Layouts ;; Layouts
(defun render-layout-html (title description tree-content) (defun render-layout-html (title description navigator-active tree-content)
"Render the HTML layout with the given title, description and content." "Render the HTML layout with the given title, description and content."
(let ((full-title (make-title title))) (let ((full-title (make-title title))
(class-name-navigator-active "nav-main--active"))
(jack-html (jack-html
"<!DOCTYPE html>" "<!DOCTYPE html>"
`(:html (@ :lang "en") `(:html (@ :lang "en")
@ -97,15 +98,15 @@
(:li.nav-main__item (:li.nav-main__item
(:a.nav-main__link.nav-main__link--logo (@ :href "/") (:img.nav-main__logo (@ :alt "Django LiveView" :src "/img/logo.webp")))) (:a.nav-main__link.nav-main__link--logo (@ :href "/") (:img.nav-main__logo (@ :alt "Django LiveView" :src "/img/logo.webp"))))
(:li.nav-main__item (:li.nav-main__item
(:a.button.nav-main__link (@ :href "/docs/install/") "Docs")) (:a.button.nav-main__link (@ :href "/docs/install/" :class ,(when (string= "docs" navigator-active) class-name-navigator-active)) "Docs"))
(:li.nav-main__item (:li.nav-main__item
(:a.button.nav-main__link (@ :href "/tutorials/") "Tutorials")) (:a.button.nav-main__link (@ :href "/tutorials/" :class ,(when (string= "tutorials" navigator-active) class-name-navigator-active)) "Tutorials"))
(:li.nav-main__item (:li.nav-main__item
(:a.button.nav-main__link (@ :href "https://django-liveview-demo.andros.dev/" :target "_blank") "Demo")) (:a.button.nav-main__link (@ :href "https://django-liveview-demo.andros.dev/" :target "_blank") "Demo"))
(:li.nav-main__item (:li.nav-main__item
(:a.button.nav-main__link (@ :href "/books/") "Books")) (:a.button.nav-main__link (@ :href "/books/" :class ,(when (string= "books" navigator-active) class-name-navigator-active)) "Books"))
(:li.nav-main__item (:li.nav-main__item
(:a.button.nav-main__link (@ :href "/source-code/") "Source code")))))) (:a.button.nav-main__link (@ :href "/source-code/" :class ,(when (string= "source code" navigator-active) class-name-navigator-active)) "Source code"))))))
,tree-content ,tree-content
(:footer.footer (:footer.footer
(:div.container (:div.container
@ -121,6 +122,7 @@
"Default render function by home page." "Default render function by home page."
(let* ((title (org-element-property :raw-value page-tree)) (let* ((title (org-element-property :raw-value page-tree))
(description (org-element-property :DESCRIPTION page-tree)) (description (org-element-property :DESCRIPTION page-tree))
(navigator-active (org-element-property :NAVIGATOR-ACTIVE page-tree))
(path (org-element-property :CUSTOM_ID page-tree)) (path (org-element-property :CUSTOM_ID page-tree))
(content (org-export-data-with-backend (content (org-export-data-with-backend
(org-element-contents page-tree) (org-element-contents page-tree)
@ -130,6 +132,7 @@
(render-layout-html (render-layout-html
title title
description description
navigator-active
(jack-html `(:main.main (jack-html `(:main.main
(:section (:section
(:div.container ,content))))))) (:div.container ,content)))))))
@ -139,6 +142,7 @@
(let* ((title (org-element-property :TITLE page-tree)) (let* ((title (org-element-property :TITLE page-tree))
(path (org-element-property :CUSTOM_ID page-tree)) (path (org-element-property :CUSTOM_ID page-tree))
(description (org-element-property :DESCRIPTION page-tree)) (description (org-element-property :DESCRIPTION page-tree))
(navigator-active (org-element-property :NAVIGATOR-ACTIVE page-tree))
(content (org-export-data-with-backend (content (org-export-data-with-backend
(org-element-contents page-tree) (org-element-contents page-tree)
'one-ox nil)) 'one-ox nil))
@ -147,6 +151,7 @@
(render-layout-html (render-layout-html
title title
description description
navigator-active
(jack-html `(:main.main (jack-html `(:main.main
(:section.hero (:section.hero
(:div.container (:div.container
@ -161,6 +166,7 @@
"Default render function by home page." "Default render function by home page."
(let* ((title (org-element-property :raw-value page-tree)) (let* ((title (org-element-property :raw-value page-tree))
(description (org-element-property :DESCRIPTION page-tree)) (description (org-element-property :DESCRIPTION page-tree))
(navigator-active (org-element-property :NAVIGATOR-ACTIVE page-tree))
(path (org-element-property :CUSTOM_ID page-tree)) (path (org-element-property :CUSTOM_ID page-tree))
(content (org-export-data-with-backend (content (org-export-data-with-backend
(org-element-contents page-tree) (org-element-contents page-tree)
@ -170,6 +176,7 @@
(render-layout-html (render-layout-html
title title
description description
navigator-active
(jack-html `(:div.container.docs (jack-html `(:div.container.docs
(:aside.aside-docs (:aside.aside-docs
(:nav.nav-docs (:nav.nav-docs
@ -198,12 +205,13 @@
(:a.nav-docs__link (@ :href "/docs/faq/") "FAQ")) (:a.nav-docs__link (@ :href "/docs/faq/") "FAQ"))
))) )))
(:main.main.main--docs (:main.main.main--docs
,content)))))) ,content))))))
(defun one-custom-default-tutorials (page-tree pages _global) (defun one-custom-default-tutorials (page-tree pages _global)
"Default render function by tutorials page." "Default render function by tutorials page."
(let* ((title (org-element-property :raw-value page-tree)) (let* ((title (org-element-property :raw-value page-tree))
(description (org-element-property :DESCRIPTION page-tree)) (description (org-element-property :DESCRIPTION page-tree))
(navigator-active (org-element-property :NAVIGATOR-ACTIVE page-tree))
(path (org-element-property :CUSTOM_ID page-tree)) (path (org-element-property :CUSTOM_ID page-tree))
(content (org-export-data-with-backend (content (org-export-data-with-backend
(org-element-contents page-tree) (org-element-contents page-tree)
@ -213,6 +221,7 @@
(render-layout-html (render-layout-html
title title
description description
navigator-active
(jack-html `(:main.main (jack-html `(:main.main
(:section.tutorials (:section.tutorials
(:div.container ,content))))))) (:div.container ,content)))))))