mirror of
https://github.com/Django-LiveView/docs.git
synced 2024-11-10 02:45:42 +01:00
Update tutorial
This commit is contained in:
parent
dee4c69947
commit
2f109f165b
302
one.org
302
one.org
@ -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:
|
||||||
|
Loading…
Reference in New Issue
Block a user