Django SEO app, integrating external data like 'Best {{ product }} of the year'

StackOverflow https://stackoverflow.com/questions/23630776

  •  21-07-2023
  •  | 
  •  

Question

I am trying to integrate external data in my metatags. What I want to achieve - by entering in Title field (in admin) "Details for {{ product.name }}" I would like to get to get automaticaly "Details for Hadron Collider" as a result in a browser. I have this in my template

{% load seo %}
{% get_metadata for product as metadata %}
{{ metadata.title }}

and I am passing Product object to the template, but what I get as a result is unchanged "Details for {{ product.name }}", so {{ value }} won't be populated / parsed? I have read the docs http://django-seo.readthedocs.org/en/latest/reference/administrators.html, it looks so simple

If you would like to reference the relevant model instance, you type the name of the model surrounded by two braces. For example Buy {{ product }} today!. You can go further and reference different fields from the relevant instance, for example By {{ product.name }} today!.

Though it doesn't work for me. Please, help. Probably I am doing something wrong.

Était-ce utile?

La solution

Ok, after days of depression :) I solved it, at least for my project and currently only for Models, but for ModelInstance and Views it's almost I will make it later, it has the same problem in my case. I am quite new to Django, so a better solution may exist, I found this one.

I use Django 1.6.4, Python 2.7, multilingual project (Django Transmeta for model translation)

The problems: 1. variable substitution in models, model instances and views doesn't work. So, if we pass an object to DjangoSEO it won't substitute e.g. {{ product }}, {{ product.name }} variables. According to documentation it should. The problem, for Model is in backends.py, ModelBackend class. Function _resolve_value doesn't pass object to the function _resolve, which is supposed to populate meta tags with object properties. Here are the functions with slight changes that work for me.

def _resolve_value(self, name):
    value = super(ModelMetadataBase, self)._resolve_value(name)
    try:
        return _resolve(value, self._content_object) 
    except AttributeError:
        return value

def _resolve(value, model_instance=None, context=None):
    """ Resolves any template references in the given value. """

    if isinstance(value, basestring) and "{" in value:
        if context is None:
            context = Context()
        if model_instance is not None:
            context[model_instance.__class__.__name__.lower()] = model_instance
    t = Template(value)
    value = t.render(context)
return value

Also, in the file base.py, function get_linked_metadata we have to attach our object to Metadata instances like this:

if ModelMetadata is not None:
    try:
        model_md = ModelMetadata.objects.get(_content_type=content_type, _language=language)
    except ModelMetadata.DoesNotExist:
        model_md = ModelMetadata(_content_type=content_type, _language=language)

    model_md._content_object = obj
    instances.append(model_md)

And the problem 2 - DjangoSEO was using one Metadata instance for any language, even with option use_i18n = True. So, add _language=language as mentioned above.

Django SEO app is quite good, it has everything SEO needs (if it works :), so there is no reason to reinvent the wheel.

Autres conseils

You need to wrap your variables in html tags.

{% load seo %}
{% get_metadata for product as metadata %}
<html>
<head>
    <title>{{ metadata.title}}</title>
</head>
<body></body>
</html>
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top