Update tutorial

This commit is contained in:
Andros Fenollosa 2024-03-15 12:52:48 +01:00
parent dee4c69947
commit 2f109f165b

302
one.org
View File

@ -111,56 +111,58 @@ Actions are where business logic is stored. The place where you write the functi
In every app you can create a folder called ~actions~ and inside it a file for each page. For example, ~home.py~ for the home page. The file will have the following structure: In every app you can create a folder called ~actions~ and inside it a file for each page. For example, ~home.py~ for the home page. The file will have the following structure:
#+BEGIN_SRC python #+BEGIN_SRC python
# my_app/actions/home.py # my_app/actions/home.py
from liveview.context_processors import get_global_context from liveview.context_processors import get_global_context
from core import settings from core import settings
from liveview.utils import ( from liveview.utils import (
get_html, get_html,
update_active_nav, update_active_nav,
enable_lang, enable_lang,
loading, loading,
) )
from django.templatetags.static import static from django.utils.translation import gettext as _
from django.templatetags.static import static
from django.urls import reverse
template = "pages/home.html" template = "pages/home.html"
# Database # Database
# Functions # Functions
async def get_context(consumer=None): async def get_context(consumer=None):
context = get_global_context(consumer=consumer) context = get_global_context(consumer=consumer)
# Update context # Update context
context.update( context.update(
{ {
"url": settings.DOMAIN_URL + reverse("home"), "url": settings.DOMAIN_URL + reverse("home"),
"title": _("Home") + " | Home", "title": _("Home") + " | Home",
"meta": { "meta": {
"description": _("Home page of the website"), "description": _("Home page of the website"),
"image": f"{settings.DOMAIN_URL}{static('img/seo/og-image.jpg')}", "image": f"{settings.DOMAIN_URL}{static('img/seo/og-image.jpg')}",
}, },
"active_nav": "home", "active_nav": "home",
"page": template, "page": template,
} }
) )
return context return context
@enable_lang @enable_lang
@loading @loading
async def send_page(consumer, client_data, lang=None): async def send_page(consumer, client_data, lang=None):
# Nav # Nav
await update_active_nav(consumer, "home") await update_active_nav(consumer, "home")
# Main # Main
my_context = await get_context(consumer=consumer) my_context = await get_context(consumer=consumer)
html = await get_html(template, my_context) html = await get_html(template, my_context)
data = { data = {
"action": client_data["action"], "action": client_data["action"],
"selector": "#main", "selector": "#main",
"html": html, "html": html,
} }
data.update(my_context) data.update(my_context)
await consumer.send_html(data) await consumer.send_html(data)
#+END_SRC #+END_SRC
Let's explain each part. Let's explain each part.
@ -863,7 +865,7 @@ urlpatterns = [
Run the server. Run the server.
#+BEGIN_SRC sh #+BEGIN_SRC sh
python manage.py runserver python3 manage.py runserver
#+END_SRC #+END_SRC
And open the browser at ~http://localhost:8000/~. You should see the home page with a button that generates a random number when clicked. And open the browser at ~http://localhost:8000/~. You should see the home page with a button that generates a random number when clicked.
@ -883,23 +885,217 @@ The next step is to create a more complex application. You can read other [[#/tu
:DESCRIPTION: Create a multilingual website with subdomains. :DESCRIPTION: Create a multilingual website with subdomains.
:END: :END:
Here you will learn how to create a multilingual website using Django LiveView. We recommend using subdomains to define the language (~en.example.com~, ~es.example.com~...), instead of using prefixes in addresses (~example.com/en/blog/~, ~example.com/es/blog/~). They simplify SEO, maintain consistency in the Sitemap and are easy to test. Here you will learn how to create a multilingual website using Django LiveView.
We using subdomains to define the language (~en.example.com~, ~es.example.com~...), instead of using prefixes in addresses (~example.com/en/blog/~, ~example.com/es/blog/~). They simplify SEO, maintain consistency in the Sitemap and are easy to test.
We will use the following structure:
- ~example.com~ and ~en.example.com~ for English.
- ~es.example.com~ for Spanish.
** 1. Configure the subdomains ** 1. Configure the subdomains
** 2. Create the subdomains In your ~settings.py~ file, add all domains that will be used.
** 3. Configure the languages #+BEGIN_SRC python
ALLOWED_HOSTS = ["example.com", "en.example.com", "es.example.com"]
#+END_SRC
** 4. Redirection with Middleware ** 2. Configure the languages
** 5. First text And add or modify the following settings in the same file (~settings.py~).
** 6. Make messages #+BEGIN_SRC python
# Languages
** 7. Compile messages # Enable internationalization
USE_I18N = True
** 8. Selector of languages # Default language
LANGUAGE_CODE = "en"
# Available languages
LANGUAGES = [
("en", _("English")),
("es", _("Spanish")),
]
# Locale paths
LOCALE_PATHS = (BASE_DIR / "locale/",)
#+END_SRC
** 3. Redirection with Middleware
Create a middleware that redirects the user to the correct subdomain and sets the language. If the user enters ~en.example.com~ or ~example.com~, English language will be activated. If the user enters ~es.example.com~, Spanish language will be activated. And if the user enters ~en.example.com~, it will be redirected to ~example.com~.
Create a file called ~middlewares.py~ in your project folder and add the following code.
#+BEGIN_SRC python
from django.utils import translation
from django.conf import settings
from django.utils.translation import get_language
from django.http import HttpResponseRedirect
def language_middleware(get_response):
# One-time configuration and initialization.
def middleware(request):
# Code to be executed for each request before
# the view (and later middleware) are called.
# Set the language based on the domain
# Example:
# "example.com" and "en.example.com" -> en
# "es.example.com" -> es
# Get the domain from the request
domain = request.META["HTTP_HOST"]
# Get the subdomain
domain_list = domain.split(".")
subdomain = domain_list[0] if len(domain_list) == 3 else None
# Set the language
if get_language() != subdomain:
translation.activate(subdomain)
# Redirect default language to main domain
# Example: "en.example.com" -> "example.com"
if subdomain == settings.LANGUAGE_CODE:
return HttpResponseRedirect("http://example.com")
response = get_response(request)
# Code to be executed for each request/response after
# the view is called.
return response
return middleware
#+END_SRC
Now, add the middleware to the ~MIDDLEWARE~ list in ~settings.py~.
#+BEGIN_SRC python
MIDDLEWARE = [
...
"middlewares.language_middleware",
]
#+END_SRC
** 4. Set multilingual texts
In any of your HTML templates, you can use translation tags to display multilingual texts.
#+BEGIN_SRC
{% load i18n %}
<h1>{% trans "Hello" %}</h1>
<p>{% blocktrans %}This is a multilingual website.{% endblocktrans %}</p>
#+END_SRC
For titles and descriptions, you can use the ~meta~ dictionary in the action with ~_("text")~ to translate the texts.
#+BEGIN_SRC python
from liveview.context_processors import get_global_context
from core import settings
from liveview.utils import (
get_html,
update_active_nav,
enable_lang,
loading,
)
from django.utils.translation import gettext as _
from django.templatetags.static import static
from django.urls import reverse
...
context.update(
{
"url": settings.DOMAIN_URL + reverse("home"),
"title": _("Home") + " | Home",
"meta": {
"description": _("Home page of the website"),
},
}
)
...
#+END_SRC
For the url of the page, you can edit the ~urls.py~ file to include the language.
#+BEGIN_SRC python
from django.urls import path
from django.utils.translation import gettext as _
from .views import home
urlpatterns = [
path(_("home") + "/", home, name="home"),
path(_("about") + "/", about, name="about"),
]
#+END_SRC
** 5. Make messages
Create the ~locale~ folder in the root of your project and run the following commands.
#+BEGIN_SRC sh
./manage.py makemessages -l en
./manage.py makemessages -l es
#+END_SRC
The files ~locale/en/LC_MESSAGES/django.po~ and ~locale/es/LC_MESSAGES/django.po~ will be created. You can edit them with a text editor or use a translation tool like [[https://poedit.net/][Poedit]].
** 6. Compile messages
After translating the texts, compile the messages.
#+BEGIN_SRC sh
./manage.py compilemessages
#+END_SRC
Your multilingual website is ready. You can test it by entering ~example.com~, ~en.example.com~ and ~es.example.com~.
** 7. Selector of languages
You can create a selector of languages in the header of your website.
#+BEGIN_SRC html
{% load i18n %}
{% get_current_language as CURRENT_LANGUAGE %}
{% get_available_languages as AVAILABLE_LANGUAGES %}
<ul>
{# Display the current language #}
<li>
<a href="#" disabled>{{ CURRENT_LANGUAGE }}</a>
</li>
{# Display the other languages #}
{% for language in AVAILABLE_LANGUAGES %}
{% if language.0 != CURRENT_LANGUAGE %}
<li>
<a href="http{% if request.is_secure %}s{% endif %}://{{ language.0 }}.{{ DOMAIN }}">
{{ language.0 }}
</a>
</li>
{% endif %}
{% endfor %}
</ul>
#+END_SRC
The above code will create a list of languages with the current language disabled.
Or also simple links with the subdomain.
#+BEGIN_SRC html
<a href="http://en.example.com">
English
</a>
<a href="http://es.example.com">
Español
</a>
{% endfor %}
* Source code * Source code
:PROPERTIES: :PROPERTIES: