2010-02-02 123 views

回答

2

这是一个模板标签库。例如:

{% load cache %} 

加载caching tags

自定义标记可以被定义并放置定义here你的项目结构中。

+0

其中定义'缓存'?? – zjm1126 2010-02-02 02:08:58

+0

http://code.djangoproject.com/browser/django/trunk/django/templatetags – danivovich 2010-02-02 02:10:28

1

这是加载使他们在模板文件中使用的其它地区提供一组特定的其他模板标签(在这种情况下,评论专用标签)的模板标签。

因此,举例来说,你将能够使用其他意见应用程序专用标签,如:

{% get_comment_count for entry as comment_count %} 

你可以在这里获得更多的信息:http://docs.djangoproject.com/en/dev/ref/contrib/comments/#comment-template-tags

这里:http://docs.djangoproject.com/en/dev/ref/templates/builtins/#load

要了解如何使一组自定义模板标签自己,如何使它们可通过相同的方法来使用,请看这里:http://docs.djangoproject.com/en/dev/howto/custom-template-tags/#howto-custom-template-tags

1

正如其他答案指出的,comments是一个模板标签。

要回答你的问题:

其中 '意见'

django/contrib/comments/templatetags/comments.py

这里定义你去:http://github.com/django/django/blob/master/django/contrib/comments/templatetags/comments.py

来源:

from django import template 
from django.template.loader import render_to_string 
from django.conf import settings 
from django.contrib.contenttypes.models import ContentType 
from django.contrib import comments 
from django.utils.encoding import smart_unicode 

register = template.Library() 

class BaseCommentNode(template.Node): 
    """ 
    Base helper class (abstract) for handling the get_comment_* template tags. 
    Looks a bit strange, but the subclasses below should make this a bit more 
    obvious. 
    """ 

    #@classmethod 
    def handle_token(cls, parser, token): 
    """Class method to parse get_comment_list/count/form and return a Node.""" 
    tokens = token.contents.split() 
    if tokens[1] != 'for': 
     raise template.TemplateSyntaxError("Second argument in %r tag must be 'for'" % tokens[0]) 

    # {% get_whatever for obj as varname %} 
    if len(tokens) == 5: 
     if tokens[3] != 'as': 
     raise template.TemplateSyntaxError("Third argument in %r must be 'as'" % tokens[0]) 
     return cls(
     object_expr = parser.compile_filter(tokens[2]), 
     as_varname = tokens[4], 
     ) 

    # {% get_whatever for app.model pk as varname %} 
    elif len(tokens) == 6: 
     if tokens[4] != 'as': 
     raise template.TemplateSyntaxError("Fourth argument in %r must be 'as'" % tokens[0]) 
     return cls(
     ctype = BaseCommentNode.lookup_content_type(tokens[2], tokens[0]), 
     object_pk_expr = parser.compile_filter(tokens[3]), 
     as_varname = tokens[5] 
     ) 

    else: 
     raise template.TemplateSyntaxError("%r tag requires 4 or 5 arguments" % tokens[0]) 

    handle_token = classmethod(handle_token) 

    #@staticmethod 
    def lookup_content_type(token, tagname): 
    try: 
     app, model = token.split('.') 
     return ContentType.objects.get(app_label=app, model=model) 
    except ValueError: 
     raise template.TemplateSyntaxError("Third argument in %r must be in the format 'app.model'" % tagname) 
    except ContentType.DoesNotExist: 
     raise template.TemplateSyntaxError("%r tag has non-existant content-type: '%s.%s'" % (tagname, app, model)) 
    lookup_content_type = staticmethod(lookup_content_type) 

    def __init__(self, ctype=None, object_pk_expr=None, object_expr=None, as_varname=None, comment=None): 
    if ctype is None and object_expr is None: 
     raise template.TemplateSyntaxError("Comment nodes must be given either a literal object or a ctype and object pk.") 
    self.comment_model = comments.get_model() 
    self.as_varname = as_varname 
    self.ctype = ctype 
    self.object_pk_expr = object_pk_expr 
    self.object_expr = object_expr 
    self.comment = comment 

    def render(self, context): 
    qs = self.get_query_set(context) 
    context[self.as_varname] = self.get_context_value_from_queryset(context, qs) 
    return '' 

    def get_query_set(self, context): 
    ctype, object_pk = self.get_target_ctype_pk(context) 
    if not object_pk: 
     return self.comment_model.objects.none() 

    qs = self.comment_model.objects.filter(
     content_type = ctype, 
     object_pk = smart_unicode(object_pk), 
     site__pk  = settings.SITE_ID, 
    ) 

    # The is_public and is_removed fields are implementation details of the 
    # built-in comment model's spam filtering system, so they might not 
    # be present on a custom comment model subclass. If they exist, we 
    # should filter on them. 
    field_names = [f.name for f in self.comment_model._meta.fields] 
    if 'is_public' in field_names: 
     qs = qs.filter(is_public=True) 
    if getattr(settings, 'COMMENTS_HIDE_REMOVED', True) and 'is_removed' in field_names: 
     qs = qs.filter(is_removed=False) 

    return qs 

    def get_target_ctype_pk(self, context): 
    if self.object_expr: 
     try: 
     obj = self.object_expr.resolve(context) 
     except template.VariableDoesNotExist: 
     return None, None 
     return ContentType.objects.get_for_model(obj), obj.pk 
    else: 
     return self.ctype, self.object_pk_expr.resolve(context, ignore_failures=True) 

    def get_context_value_from_queryset(self, context, qs): 
    """Subclasses should override this.""" 
    raise NotImplementedError 

class CommentListNode(BaseCommentNode): 
    """Insert a list of comments into the context.""" 
    def get_context_value_from_queryset(self, context, qs): 
    return list(qs) 

class CommentCountNode(BaseCommentNode): 
    """Insert a count of comments into the context.""" 
    def get_context_value_from_queryset(self, context, qs): 
    return qs.count() 

class CommentFormNode(BaseCommentNode): 
    """Insert a form for the comment model into the context.""" 

    def get_form(self, context): 
    ctype, object_pk = self.get_target_ctype_pk(context) 
    if object_pk: 
     return comments.get_form()(ctype.get_object_for_this_type(pk=object_pk)) 
    else: 
     return None 

    def render(self, context): 
    context[self.as_varname] = self.get_form(context) 
    return '' 

class RenderCommentFormNode(CommentFormNode): 
    """Render the comment form directly""" 

    #@classmethod 
    def handle_token(cls, parser, token): 
    """Class method to parse render_comment_form and return a Node.""" 
    tokens = token.contents.split() 
    if tokens[1] != 'for': 
     raise template.TemplateSyntaxError("Second argument in %r tag must be 'for'" % tokens[0]) 

    # {% render_comment_form for obj %} 
    if len(tokens) == 3: 
     return cls(object_expr=parser.compile_filter(tokens[2])) 

    # {% render_comment_form for app.models pk %} 
    elif len(tokens) == 4: 
     return cls(
     ctype = BaseCommentNode.lookup_content_type(tokens[2], tokens[0]), 
     object_pk_expr = parser.compile_filter(tokens[3]) 
     ) 
    handle_token = classmethod(handle_token) 

    def render(self, context): 
    ctype, object_pk = self.get_target_ctype_pk(context) 
    if object_pk: 
     template_search_list = [ 
     "comments/%s/%s/form.html" % (ctype.app_label, ctype.model), 
     "comments/%s/form.html" % ctype.app_label, 
     "comments/form.html" 
     ] 
     context.push() 
     formstr = render_to_string(template_search_list, {"form" : self.get_form(context)}, context) 
     context.pop() 
     return formstr 
    else: 
     return '' 

class RenderCommentListNode(CommentListNode): 
    """Render the comment list directly""" 

    #@classmethod 
    def handle_token(cls, parser, token): 
    """Class method to parse render_comment_list and return a Node.""" 
    tokens = token.contents.split() 
    if tokens[1] != 'for': 
     raise template.TemplateSyntaxError("Second argument in %r tag must be 'for'" % tokens[0]) 

    # {% render_comment_list for obj %} 
    if len(tokens) == 3: 
     return cls(object_expr=parser.compile_filter(tokens[2])) 

    # {% render_comment_list for app.models pk %} 
    elif len(tokens) == 4: 
     return cls(
     ctype = BaseCommentNode.lookup_content_type(tokens[2], tokens[0]), 
     object_pk_expr = parser.compile_filter(tokens[3]) 
     ) 
    handle_token = classmethod(handle_token) 

    def render(self, context): 
    ctype, object_pk = self.get_target_ctype_pk(context) 
    if object_pk: 
     template_search_list = [ 
     "comments/%s/%s/list.html" % (ctype.app_label, ctype.model), 
     "comments/%s/list.html" % ctype.app_label, 
     "comments/list.html" 
     ] 
     qs = self.get_query_set(context) 
     context.push() 
     liststr = render_to_string(template_search_list, { 
     "comment_list" : self.get_context_value_from_queryset(context, qs) 
     }, context) 
     context.pop() 
     return liststr 
    else: 
     return '' 

# We could just register each classmethod directly, but then we'd lose out on 
# the automagic docstrings-into-admin-docs tricks. So each node gets a cute 
# wrapper function that just exists to hold the docstring. 

#@register.tag 
def get_comment_count(parser, token): 
    """ 
    Gets the comment count for the given params and populates the template 
    context with a variable containing that value, whose name is defined by the 
    'as' clause. 

    Syntax:: 

    {% get_comment_count for [object] as [varname] %} 
    {% get_comment_count for [app].[model] [object_id] as [varname] %} 

    Example usage:: 

    {% get_comment_count for event as comment_count %} 
    {% get_comment_count for calendar.event event.id as comment_count %} 
    {% get_comment_count for calendar.event 17 as comment_count %} 

    """ 
    return CommentCountNode.handle_token(parser, token) 

#@register.tag 
def get_comment_list(parser, token): 
    """ 
    Gets the list of comments for the given params and populates the template 
    context with a variable containing that value, whose name is defined by the 
    'as' clause. 

    Syntax:: 

    {% get_comment_list for [object] as [varname] %} 
    {% get_comment_list for [app].[model] [object_id] as [varname] %} 

    Example usage:: 

    {% get_comment_list for event as comment_list %} 
    {% for comment in comment_list %} 
     ... 
    {% endfor %} 

    """ 
    return CommentListNode.handle_token(parser, token) 

#@register.tag 
def render_comment_list(parser, token): 
    """ 
    Render the comment list (as returned by ``{% get_comment_list %}``) 
    through the ``comments/list.html`` template 

    Syntax:: 

    {% render_comment_list for [object] %} 
    {% render_comment_list for [app].[model] [object_id] %} 

    Example usage:: 

    {% render_comment_list for event %} 

    """ 
    return RenderCommentListNode.handle_token(parser, token) 

#@register.tag 
def get_comment_form(parser, token): 
    """ 
    Get a (new) form object to post a new comment. 

    Syntax:: 

    {% get_comment_form for [object] as [varname] %} 
    {% get_comment_form for [app].[model] [object_id] as [varname] %} 
    """ 
    return CommentFormNode.handle_token(parser, token) 

#@register.tag 
def render_comment_form(parser, token): 
    """ 
    Render the comment form (as returned by ``{% render_comment_form %}``) through 
    the ``comments/form.html`` template. 

    Syntax:: 

    {% render_comment_form for [object] %} 
    {% render_comment_form for [app].[model] [object_id] %} 
    """ 
    return RenderCommentFormNode.handle_token(parser, token) 

#@register.simple_tag 
def comment_form_target(): 
    """ 
    Get the target URL for the comment form. 

    Example:: 

    <form action="{% comment_form_target %}" method="post"> 
    """ 
    return comments.get_form_target() 

#@register.simple_tag 
def get_comment_permalink(comment, anchor_pattern=None): 
    """ 
    Get the permalink for a comment, optionally specifying the format of the 
    named anchor to be appended to the end of the URL. 

    Example:: 
    {{ get_comment_permalink comment "#c%(id)s-by-%(user_name)s" }} 
    """ 

    if anchor_pattern: 
    return comment.get_absolute_url(anchor_pattern) 
    return comment.get_absolute_url() 

register.tag(get_comment_count) 
register.tag(get_comment_list) 
register.tag(get_comment_form) 
register.tag(render_comment_form) 
register.simple_tag(comment_form_target) 
register.simple_tag(get_comment_permalink) 
register.tag(render_comment_list)