我有一个网站有几百页,其中可能有75%的网页是静态内容,其余的则适合典型的“网络应用程序”模型。我的偏好是Django,所以我一直在寻找基于此的解决方案。我可以在Django内部使用像Hyde这样的东西吗?
内容是非常定制的 - 大多数页面几乎没有超出基本的网站chrome,并且足够复杂,以HTML编写它们变得更加简单,而不是试图将富文本编辑器转换为提供正确的输出。所以我现在要做的方向是定义模板中的内容 - 我有一个视图,并使用传入路径作为模板路径。这使得网站上的每个页面成为文件系统中的一个页面(易于浏览,易于在修订控制中进行跟踪),但可让每个页面共享任意数量的常见元素(页眉,页脚,导航)并将其自己的数据注入他们根据需要。但是,这在很多细节中陷入了困境。例如:
- 与其他页面共享页面数据。例如,页面定义的标题应显示在其他页面上的导航菜单中,等等。我发现this question关于从模板中获取块值,但这看起来真的很复杂(并且不可缩放)。
- 相关问题:如果我将某些东西定义为块,我只能使用它一次。我已经看到{%block title%}的例子 - 通常会在页面的多个位置出现 - 在没有很好的解决方案的情况下,数次出现。
- 多重/灵活继承。对于面包屑我可能想从页面的祖先继承,但是对于布局,我可能想要从其他东西继承(例如,一列与两列基本模板)。
我觉得这些具体问题都自己解决的,主要是通过使用包括和自定义模板标签,但看着这条道路我看到堆放在黑客,我想避免的顶级黑客 - 这需要成为一个相当简单且易于维护的系统。
在研究这些过程中,我碰到了Hyde,这似乎解决了很多这些问题。特别是,我真的很喜欢它具有网站结构的感觉,并且它为页面提供了一些很好的工具来浏览。
但我仍然有所有的动态片断,这真的需要无缝配合。所以我为内容页面做的任何事情都应该适用于动态应用程序的任何模板。另外,我非常喜欢“每页模板”方法,我可以通过将其路径添加到urls.py并指定自定义视图来改变任何特定页面的处理方式。
这种类型的用例是否有很好的解决方案?更一般地说,这只是Django不应该被要求做的事情吗?在我看来,我试图在这里使用文件系统作为CMS数据库,这似乎可能导致扩展问题,但Django似乎很好地处理和缓存模板内容,并且在查看一些现有的CMS解决方案(django-cms,feincms,fiber)我真的不喜欢有一个静态内容解决方案和一个完全不同的交互式内容解决方案。
编辑
这里是我使用自定义标签来处理页面元/配置:
- 一个字典页面数据在顶层传递(从而使标签能写然后在堆栈中的代码更高可以将其读回)
- 自定义数据标签允许页面将数据写入此页面数据
- 其他自定义标签读取和渲染结构(导航,面包屑等),从数据
主要部分是一个标签,将读取的数据(写为JSON)到全局字典:
class PageInfoNode(Node):
def __init__(self, page_info):
self.title = page_info['title']
self.breadcrumb_title = page_info.get('breadcrumb_title', self.title)
self.show_breadcrumb = page_info.get('show_breadcrumb', False)
self.nav_title = page_info.get('nav_title', self.breadcrumb_title)
self.side_nav = page_info.get('side_nav', None)
def render(self, context):
# 'page_info' must be set someplace higher in the context stack
page_info = context['page_info']
page_info['title'] = self.title
page_info['nav_title'] = self.nav_title
if self.show_breadcrumb:
if 'breadcrumb' in page_info:
page_info['breadcrumb'] = [self.breadcrumb_title] + page_info['breadcrumb']
else:
page_info['breadcrumb'] = [self.breadcrumb_title]
if self.side_nav != None:
page_info['side_nav'] = self.side_nav
return ''
@register.tag
def pageinfo(parser, token):
nodelist = parser.parse(('endpageinfo',))
parser.delete_first_token()
return PageInfoNode(json.loads(nodelist.render(Context())))
每个页面将其数据,如:
{% block data %}
{{ block.super }}
{% load my_page_tags %}
{% pageinfo %}
{
"title": "My Page Title",
"show_breadcrumb": true,
"side_nav": ["/section1/page.html", "/section2/page.html"]
}
{% endpageinfo %}
{% endblock data %}
这工作,但似乎真的不透明的和脆弱的:
- 水珠al dict需要以某种方式添加 - 现在我在视图中执行此操作,但我认为自定义上下文处理器会更好
- 这需要位于继承的块中,以便实际渲染
- 因为我们有时需要超级数据(例如。对于面包屑),它需要调用{{block.super}},但它需要按照正确的顺序保持超级数据覆盖目标页面的数据。
我只是觉得我正在反对Django想要操作的方式,而且我希望有一些更好的方法来处理我错过的这种事情。
对不起,这个自定义标签有什么问题? – Marcin 2012-01-06 23:45:50
把你的问题放在你的问题上。 – Marcin 2012-01-09 17:38:14
如果能让他们干净地工作,我很乐意使用自定义标签。到目前为止,我对结果并不满意。 – Adam 2012-01-09 17:47:47