Conditions | 14 |
Total Lines | 99 |
Lines | 0 |
Ratio | 0 % |
Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.
For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.
Commonly applied refactorings include:
If many parameters/temporary variables are present:
Complex classes like get_translated_url() often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.
Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.
1 | import inspect |
||
65 | @register.assignment_tag(takes_context=True) |
||
66 | def get_translated_url(context, lang_code, object=None): |
||
67 | """ |
||
68 | Get the proper URL for this page in a different language. |
||
69 | |||
70 | Note that this algorithm performs a "best effect" approach to give a proper URL. |
||
71 | To make sure the proper view URL is returned, add the :class:`~parler.views.ViewUrlMixin` to your view. |
||
72 | |||
73 | Example, to build a language menu:: |
||
74 | |||
75 | <ul> |
||
76 | {% for lang_code, title in LANGUAGES %} |
||
77 | {% get_language_info for lang_code as lang %} |
||
78 | {% get_translated_url lang_code as tr_url %} |
||
79 | {% if tr_url %}<li{% if lang_code == LANGUAGE_CODE %} class="is-selected"{% endif %}><a href="{{ tr_url }}" hreflang="{{ lang_code }}">{{ lang.name_local|capfirst }}</a></li>{% endif %} |
||
80 | {% endfor %} |
||
81 | </ul> |
||
82 | |||
83 | Or to inform search engines about the translated pages:: |
||
84 | |||
85 | {% for lang_code, title in LANGUAGES %} |
||
86 | {% get_translated_url lang_code as tr_url %} |
||
87 | {% if tr_url %}<link rel="alternate" hreflang="{{ lang_code }}" href="{{ tr_url }}" />{% endif %} |
||
88 | {% endfor %} |
||
89 | |||
90 | Note that using this tag is not thread-safe if the object is shared between threads. |
||
91 | It temporary changes the current language of the view object. |
||
92 | |||
93 | The query string of the current page is preserved in the translated URL. |
||
94 | When the ``object`` variable is explicitly provided however, the query string will not be added. |
||
95 | In such situation, *django-parler* assumes that the object may point to a completely different page, |
||
96 | hence to query string is added. |
||
97 | """ |
||
98 | view = context.get('view', None) |
||
99 | request = context['request'] |
||
100 | |||
101 | if object is not None: |
||
102 | # Cannot reliable determine whether the current page is being translated, |
||
103 | # or the template code provides a custom object to translate. |
||
104 | # Hence, not passing the querystring of the current page |
||
105 | qs = '' |
||
106 | else: |
||
107 | # Try a few common object variables, the SingleObjectMixin object, |
||
108 | # The Django CMS "current_page" variable, or the "page" from django-fluent-pages and Mezzanine. |
||
109 | # This makes this tag work with most CMSes out of the box. |
||
110 | object = context.get('object', None) \ |
||
111 | or context.get('current_page', None) \ |
||
112 | or context.get('page', None) |
||
113 | |||
114 | # Assuming current page, preserve query string filters. |
||
115 | qs = request.META.get('QUERY_STRING', '') |
||
116 | |||
117 | try: |
||
118 | if view is not None: |
||
119 | # Allow a view to specify what the URL should be. |
||
120 | # This handles situations where the slug might be translated, |
||
121 | # and gives you complete control over the results of this template tag. |
||
122 | get_view_url = getattr(view, 'get_view_url', None) |
||
123 | if get_view_url: |
||
124 | with smart_override(lang_code): |
||
125 | return _url_qs(view.get_view_url(), qs) |
||
126 | |||
127 | # Now, the "best effort" part starts. |
||
128 | # See if it's a DetailView that exposes the object. |
||
129 | if object is None: |
||
130 | object = getattr(view, 'object', None) |
||
131 | |||
132 | if object is not None and hasattr(object, 'get_absolute_url'): |
||
133 | # There is an object, get the URL in the different language. |
||
134 | # NOTE: this *assumes* that there is a detail view, not some edit view. |
||
135 | # In such case, a language menu would redirect a user from the edit page |
||
136 | # to a detail page; which is still way better a 404 or homepage. |
||
137 | if isinstance(object, TranslatableModel): |
||
138 | # Need to handle object URL translations. |
||
139 | # Just using smart_override() should be enough, as a translated object |
||
140 | # should use `switch_language(self)` internally before returning an URL. |
||
141 | # However, it doesn't hurt to help a bit here. |
||
142 | with switch_language(object, lang_code): |
||
143 | return _url_qs(object.get_absolute_url(), qs) |
||
144 | else: |
||
145 | # Always switch the language before resolving, so i18n_patterns() are supported. |
||
146 | with smart_override(lang_code): |
||
147 | return _url_qs(object.get_absolute_url(), qs) |
||
148 | except TranslationDoesNotExist: |
||
149 | # Typically projects have a fallback language, so even unknown languages will return something. |
||
150 | # This either means fallbacks are disabled, or the fallback language is not found! |
||
151 | return '' |
||
152 | |||
153 | # Just reverse the current URL again in a new language, and see where we end up. |
||
154 | # This doesn't handle translated slugs, but will resolve to the proper view name. |
||
155 | resolver_match = _get_resolver_match(request) |
||
156 | if resolver_match is None: |
||
157 | # Can't resolve the page itself, the page is apparently a 404. |
||
158 | # This can also happen for the homepage in an i18n_patterns situation. |
||
159 | return '' |
||
160 | |||
161 | with smart_override(lang_code): |
||
162 | clean_kwargs = _cleanup_urlpattern_kwargs(resolver_match.kwargs) |
||
163 | return _url_qs(reverse(resolver_match.view_name, args=resolver_match.args, kwargs=clean_kwargs, current_app=resolver_match.app_name), qs) |
||
164 | |||
201 |