Re: wagtails translate completely urls ?

334 views
Skip to first unread message
Message has been deleted

Robert Slotboom

unread,
Jun 16, 2016, 3:57:20 AM6/16/16
to Wagtail support
Hi Tonio...

Maybe the following model design will help.
The main difference is the relation between page and translation.
This way can search translations for current_lang and slug.

No need for the language prefix anymore.

In the admin the translations are moved to a panel called “translation_panels”




from django.utils.translation import ugettext_lazy as _


#_____________________________________________________________________________
# AbstractPageTranslation

class AbstractPageTranslation(models.Model):

    FR_CODE
= 'fr'
    DE_CODE
='de'
    FR_NAME
= _('french')
    DE_NAME
= _('german')
    LANG_CHOICES
= (
       
(FR_CODE, FR_NAME),
       
(DE_CODE, DE_NAME),
   
)
    TRANSLATIONS_AVAILABLE
= [key for key, val in LANG_CHOICES]
   
    language
= models.CharField(
        _
('language'),
        max_length
= 3,
        choices
= LANG_CHOICES,
        help_text
= _('The language this translation is made for.')
   
)
    title
= models.CharField(
        verbose_name
= _('title'),
        max_length
= 255,
        help_text
= _("Name as you'd like it to be seen by the public")
   
)
    slug
= models.SlugField(
        verbose_name
=_('slug'),
        max_length
=255,
        help_text
=_("The title as it will appear in URLs e.g http://domain.com/blog/[my-slug]/")
   
)


    panels
= [
       
FieldPanel('language'),
       
FieldPanel('title'),
       
FieldPanel('slug')
   
]


   
class Meta:
        verbose_name
= _('Abstract Page Translation')
        verbose_name_plural
= _('Abstract Page Translations'
       
abstract = True


   
def __str__(self):
       
return '{0} {1}'.format(self.title, self.language)

#_____________________________________________________________________________
# BasePage


class BasePage(Page):
   
   
...
   
    translation_panels
= [
       
InlinePanel('base_page_translations', max_num=4, label=_('Page translations')),
   
]
    edit_handler
= TabbedInterface([
       
ObjectList(content_panels, heading=_('Content')),
       
ObjectList(translation_panels, heading=_('Translations')),
       
ObjectList(Page.promote_panels, heading=_('Promote')),
       
ObjectList(Page.settings_panels, heading=_('Settings'), classname="settings"),
   
])
   
   
   
class Meta:
        verbose_name
= _('Basepage')


   
def route(self, request, path_components):
        current_lang
= get_language()
       
if not current_lang in AbstractPageTranslation.TRANSLATIONS_AVAILABLE:
           
raise Http404
       
       
if path_components:
            child_slug
= path_components[0]
            remaining_components
= path_components[1:]
            subpage
= self.get_children()
            subpage
= subpage.filter(
                base_page_translations__language
=current_lang
           
)
           
try:
                subpage
.get(slug=child_slug)
           
except Page.DoesNotExist:
               
raise Http404
           
return subpage.specific.route(request, remaining_components)


       
else:
           
if self.live:
               
return RouteResult(self)
           
else:
               
raise Http404




#_____________________________________________________________________________
# BasePageTranslation


class BasePageTranslation(AbstractPageTranslation):
    page
= ParentalKey('cms.BasePage', related_name='base_page_translations', verbose_name = _('page to translate'))









In the menu, urls can be generated using a template tag, current_lang and item.base_page_translations.

In my opinion you should transfer some methods to a model manager.

à bientôt!


Robert 



Robert Slotboom

unread,
Jun 16, 2016, 4:03:13 AM6/16/16
to Wagtail support
By the way, HY is the name of an old camion I once owned :-)


Message has been deleted

Robert Slotboom

unread,
Jun 16, 2016, 9:17:28 AM6/16/16
to Wagtail support
Hi Tonio,

Not exactly... The idea is to create the following database layout:

Page can have zero or more Translation.
Translation must be unique for page_id + language_code.

P1    id = 1


T1    id
= 1, p_id = 1, lang = 'fr'

T2    id
= 2, p_id = 1, lang = 'de'

T3    id
= 3, p_id = 1, lang = 'nl'

T4    id
= 4, p_id = 1, lang = 'nl' ERROR lang & p_id already exist.


In Django like this:

class MyPage(model.Model):
   
   
"""
    Model to store values for the default language
    """

    title
= models.CharField(
        verbose_name
= _('title'),
        max_length
= 255,
        help_text
= _("Name as you'd like it to be seen by the public")
   
)
    slug
= models.SlugField(
        verbose_name
=_('slug'),
        max_length
=255,
        help_text
=_("The title as it will appear in URLs e.g http://domain.com/blog/[my-slug]/")
   
)

    body
= models.textField(blank=True)




class PageTranslation(model.Model):


   
"""
    Model to store the values for a specific language
    """

    page
= models.ForeignKey(MyPage)
    language
= models.CharField(choices = LANG_CHOICES)
   
    title
= models.CharField()
    slug
= models.SlugField()
    body
= models.textField(blank=True)


   
class Meta:
        unique_together
= ('page', 'language')

In Wagtail:

class MyPage(Page):
   
    # title comes from Page
    
slug comes from Page
    body = models.textField(blank=True)

    translation_panels
= [
       
InlinePanel('my_page_translations', max_num=4, label='Page translations'),
   
]
    edit_handler
= TabbedInterface([
       
...
       
ObjectList(Page.settings_panels, heading='Settings', classname="settings"),
   
])
   

class Translation(models.Model):

    page
= ParentalKey('youapp.MyPage', related_name='my_page_translations')
    language
= models.CharField(choices = LANG_CHOICES)
    title
= models.CharField()
    body
= models.textField(blank=True)


    panels
= [
       
FieldPanel('language'),

       
...
   
]


So when adding a page, you enter the data for the default language.
For the other languages you add related translations using:

InlinePanel('my_page_translations', label='Page translations'),


Compris?

Robert

Message has been deleted

Robert Slotboom

unread,
Jun 17, 2016, 3:47:25 AM6/17/16
to Wagtail support
Hi Tonio,

Sorry I am still student I begin.

Students are already started :-)


Have a look at related_name, filter and InlinePanel


class CityPage(Page):
    
    translation_panels = [
        InlinePanel('base_page_translations'),
    ]


         def route(self, request, path_components):
            subpage = subpage.filter(
                base_page_translations__language=current_lang
            )



class CityPageTranslation(AbstractPageTranslation):
    page = ParentalKey('cms.CityPage', related_name='city_page_translations')



base_page_translations should be city_page_translations

class DetailPage(Page):
   
    translation_panels
= [
       
InlinePanel('base_page_translations'),
   
]
   
   
def route(self, request, path_components):

            subpage
= subpage.filter(
                base_page_translations__language
=current_lang
           
)


class DetailPageTranslation(AbstractPageTranslation):
    page
= ParentalKey('cms.DetailPage', related_name='detail_page_translations')


base_page_translations should be detail_page_translations

Related Name

Consider this:

We collect a translation.

translation = DetailPageTranslation.objects.all()[0]

Now we want the page this translation is made for.

translated_page = translation.page

Now all translations for this page can be collected using the related_name

page_translations = translated_page.detail_page_translations


Abstract Model

class CityPageTranslation(AbstractPageTranslation)
class DetailPageTranslation(AbstractPageTranslation)

They inherited common things.

Because some common things are alo needed in CityPage and DetailPage I suggest:

class AbstractPage(Page):

   
""" common things """    

   
class Meta:
        verbose_name
= _('Abstract Page')
        verbose_name_plural
= _('Abstract Page'
       
abstract = True



Documentation



Bon Weekend,

– Robert


Robert Slotboom

unread,
Jun 19, 2016, 5:24:07 AM6/19/16
to Wagtail support
Hi Tonio,

You can translate the pattern in routes like this:

from django.utils.translation import ugettext_lazy as _


@route(_(r'^for-(?P<target_slug>[-\w]+)/$'))




Mind the _()

In English is wil listen to:

 /page_url/for-companies/

And when translations are made for example dutch and the current language is dutch it will listen to:

 /page_url/voor-bedrijven/


More info at





Message has been deleted

Robert Slotboom

unread,
Jun 23, 2016, 12:51:36 AM6/23/16
to Wagtail support
Hi Tonio,

I did a little test.

def route(self, request, path_components):

   
if path_components:
        child_slug
= path_components[0]
        remaining_components
= path_components[1:]

       
raise
   
else:
        what_is
= self
        path
= request.path
       
raise


Result on calling the last child.
path_components       ['testkind']
child_slug            
'testkind'
self                  <StandardPage: Een eerste pagina>
remaining_components  
[]
request              
<WSGIRequest: GET '/programma/een-eerste-pagina/testkind/'>


Parent of self...

Cheers,

– Robert




Message has been deleted

Robert Slotboom

unread,
Jun 30, 2016, 8:11:22 AM6/30/16
to Wagtail support
Hello Tonio,

Strange... I have a route like this and it is working;

@route(_(r'^for-(?P<target_slug>[-\w]+)/$'))
def for_target_group(self, request, target_slug):
    target_key
= TargetGroup.get_key_for_name(target_slug)
   
if target_key:
        url
= self.get_redirect_url(
           
'events_for_target_group',
            kwargs
= {
               
'target_slug': target_slug,
               
'event_model_slug': Lecture._meta.verbose_name_plural.lower()
           
}
       
)
       
return redirect(url)


My first action would be looking at the serve method, or catching the value reverse is returning.

Good luck,


– Robert

tonio...@gmail.com

unread,
Jun 30, 2016, 2:41:05 PM6/30/16
to Wagtail support
Thanks, It's working :-D
Reply all
Reply to author
Forward
0 new messages