Author: rspivak
Date: Mon Oct 24 07:40:06 2005
New Revision: 28557

Added:
   z3lab/cpsblog/trunk/browser/blogentryform.pt   (contents, props changed)
   z3lab/cpsblog/trunk/browser/blogform.pt   (contents, props changed)
   z3lab/cpsblog/trunk/browser/macros.py   (contents, props changed)
   z3lab/cpsblog/trunk/browser/menu_macros.pt   (contents, props changed)
   z3lab/cpsblog/trunk/browser/skin/
   z3lab/cpsblog/trunk/browser/skin/__init__.py   (contents, props changed)
   z3lab/cpsblog/trunk/browser/skin/blog.pt   (contents, props changed)
   z3lab/cpsblog/trunk/browser/skin/blogentry.pt   (contents, props changed)
   z3lab/cpsblog/trunk/browser/skin/configure.zcml   (contents, props changed)
   z3lab/cpsblog/trunk/browser/skin/images/
   z3lab/cpsblog/trunk/browser/skin/images/body_back.gif   (contents, props 
changed)
   z3lab/cpsblog/trunk/browser/skin/images/header_bl.png   (contents, props 
changed)
   z3lab/cpsblog/trunk/browser/skin/images/header_br.gif   (contents, props 
changed)
   z3lab/cpsblog/trunk/browser/skin/images/header_tab.gif   (contents, props 
changed)
   z3lab/cpsblog/trunk/browser/skin/images/header_tl.gif   (contents, props 
changed)
   z3lab/cpsblog/trunk/browser/skin/images/header_tr.gif   (contents, props 
changed)
   z3lab/cpsblog/trunk/browser/skin/images/key-point_back.gif   (contents, 
props changed)
   z3lab/cpsblog/trunk/browser/skin/images/key-point_bl.gif   (contents, props 
changed)
   z3lab/cpsblog/trunk/browser/skin/images/key-point_br.gif   (contents, props 
changed)
   z3lab/cpsblog/trunk/browser/skin/images/key-point_tl.gif   (contents, props 
changed)
   z3lab/cpsblog/trunk/browser/skin/images/key-point_tr.gif   (contents, props 
changed)
   z3lab/cpsblog/trunk/browser/skin/images/menu_back.gif   (contents, props 
changed)
   z3lab/cpsblog/trunk/browser/skin/images/menu_br.gif   (contents, props 
changed)
   z3lab/cpsblog/trunk/browser/skin/images/menu_tr.gif   (contents, props 
changed)
   z3lab/cpsblog/trunk/browser/skin/images/nuxeo.png   (contents, props changed)
   z3lab/cpsblog/trunk/browser/skin/template.css   (contents, props changed)
   z3lab/cpsblog/trunk/browser/skin/template.pt   (contents, props changed)
   z3lab/cpsblog/trunk/browser/widgets/
   z3lab/cpsblog/trunk/browser/widgets/__init__.py   (contents, props changed)
   z3lab/cpsblog/trunk/browser/widgets/configure.zcml   (contents, props 
changed)
   z3lab/cpsblog/trunk/browser/widgets/fckeditor/
   z3lab/cpsblog/trunk/browser/widgets/myconfig.js   (contents, props changed)
Modified:
   z3lab/cpsblog/trunk/adapters.py
   z3lab/cpsblog/trunk/browser/blog.py
   z3lab/cpsblog/trunk/browser/blogentry.py
   z3lab/cpsblog/trunk/browser/configure.zcml
   z3lab/cpsblog/trunk/configure.zcml
Log:
- Implemented FCKEditorWidget
- Simple breadcrumbs support (based on object name)
- Added basic skin implementation
- Added custom macros mechanism



Modified: z3lab/cpsblog/trunk/adapters.py
==============================================================================
--- z3lab/cpsblog/trunk/adapters.py     (original)
+++ z3lab/cpsblog/trunk/adapters.py     Mon Oct 24 07:40:06 2005
@@ -9,6 +9,12 @@
 
 from cpsblog.interfaces import IBlogEntry, IBlog
 
+from zope.app.component.hooks import getSite
+from zope.app.traversing.namespace import SimpleHandler
+
+from zope.app.traversing.interfaces import ITraversable
+
+
 @interface.implementer(ITZInfo)
 @component.adapter(IBrowserRequest)
 def tzinfo(request):
@@ -24,3 +30,7 @@
          'modified': 'modified',
          'subjects': 'subjects',
          })
+
+class Site(SimpleHandler):
+    def traverse(self, name, ignored):
+        return getSite()

Modified: z3lab/cpsblog/trunk/browser/blog.py
==============================================================================
--- z3lab/cpsblog/trunk/browser/blog.py (original)
+++ z3lab/cpsblog/trunk/browser/blog.py Mon Oct 24 07:40:06 2005
@@ -8,6 +8,12 @@
 
 from cpsblog.interfaces import IBlog
 
+from zope.app import zapi
+from zope.app.catalog.interfaces import ICatalog
+from zope.index.text.parsetree import ParseError
+
+from cpsblog.browser.widgets import FCKEditorWidget
+
 class BlogListing:
 
     def getSortedBlogEntries(self):
@@ -21,11 +27,10 @@
 class BlogEditView(form.EditForm):
     form_fields = form.Fields(IBlog)
 
-    def renderActions(self):
-        result = []
-        for action in self.actions:
-            result.append(action.render())
-        return '\n'.join(result)
+    template = ViewPageTemplateFile('blogform.pt')
+
+    form_fields['description'].custom_widget = FCKEditorWidget
+
 
 class BlogAddView(form.AddForm):
     form_fields = form.Fields(IBlog)
@@ -39,8 +44,24 @@
 
         return blog
 
-    def renderActions(self):
-        result = []
-        for action in self.actions:
-            result.append(action.render())
-        return '\n'.join(result)
+
+class BlogView:
+
+    def search(self, query):
+        if not query:
+            return []
+        catalog = zapi.getUtility(ICatalog, 'catalog')
+        try:
+            return catalog.searchResults(searchable=query)
+        except ParseError:
+            # text index complains for 'common' words, like 'is'
+            return []
+
+    def getSortedBlogEntries(self):
+        """Return blog entries sorted on creation date in reverse order."""
+        def key(item):
+            return IZopeDublinCore(item).created
+        items = list(self.context.values())
+        items.sort(key=key, reverse=True)
+        return [zapi.getMultiAdapter((item, self.request), name='index.html')
+                for item in items]

Modified: z3lab/cpsblog/trunk/browser/blogentry.py
==============================================================================
--- z3lab/cpsblog/trunk/browser/blogentry.py    (original)
+++ z3lab/cpsblog/trunk/browser/blogentry.py    Mon Oct 24 07:40:06 2005
@@ -1,18 +1,25 @@
+# $Id$
 from cpsblog.browser.dublincore import DublinCoreViews
 from zope.component.interfaces import IFactory
 from zope.formlib import form
 from zope.app import zapi
+from zope.app.dublincore.interfaces import IZopeDublinCore
+from zope.app.pagetemplate import ViewPageTemplateFile
 
 from cpsblog.interfaces import IBlogEntry
+from cpsblog.browser.widgets import FCKEditorWidget
 
 import zope.interface
 
-class BlogEntryDetails(DublinCoreViews):
-    pass
 
 class BlogEntryEditView(form.EditForm):
     form_fields = form.Fields(IBlogEntry)
 
+    form_fields['content'].custom_widget = FCKEditorWidget
+    form_fields['summary'].custom_widget = FCKEditorWidget
+
+    template = ViewPageTemplateFile('blogentryform.pt')
+
 class BlogEntryAddView(form.AddForm):
     form_fields = form.Fields(IBlogEntry)
 
@@ -24,3 +31,29 @@
             setattr(blogentry, name, data[name])
 
         return blogentry
+
+class BlogEntryView:
+
+    def author(self):
+        creators = IZopeDublinCore(self.context).creators
+        return creators[0]
+
+    def created(self):
+        return IZopeDublinCore(self.context).created
+
+    def title(self):
+        return self.context.title
+
+    def content(self):
+        return self.context.content
+
+    def absolute_url(self):
+        return zapi.absoluteURL(self.context, self.request)
+
+#     def breadcrumbs(self):
+#         absolute_url = zapi.getMultiAdapter((self.context, self.request),
+#                                             name='absolute_url')
+#         result = ''
+#         for d in absolute_url.breadcrumbs()[:-1]:
+#             result += "<a href='%(url)s'>%(name)s</a>/" % d
+#         return result

Added: z3lab/cpsblog/trunk/browser/blogentryform.pt
==============================================================================
--- (empty file)
+++ z3lab/cpsblog/trunk/browser/blogentryform.pt        Mon Oct 24 07:40:06 2005
@@ -0,0 +1,149 @@
+<html metal:extend-macro="context/@@standard_macros/view"
+      metal:define-macro="main">
+<head>
+  <!-- XXX Need test -->
+  <div metal:fill-slot="header">
+    <metal:block use-macro="context/@@blogmenu_macros/entrymainmenu" />
+    <metal:block use-macro="context/@@blogmenu_macros/searchfield" />
+  </div>
+</head>
+
+<body>
+<div metal:fill-slot="body">
+
+<div metal:define-macro="form">
+
+<form action="." metal:define-macro="master"
+      tal:attributes="action request/URL" method="post"
+      class="edit-form" enctype="multipart/form-data"
+      id="zc.page.browser_form">
+
+<script type="text/javascript"><!--
+
+function toggleFormFieldHelp(ob,state) {
+  // ob is the label element
+  var field = ob.form[ob.htmlFor];
+  if (field) {
+    field.style.visibility = state && 'hidden' || 'visible';
+    var help = document.getElementById("field-help-for-" + field.name);
+    if (help) {
+      help.style.visibility = state && 'visible' || 'hidden';
+    }
+  }
+}
+
+//-->
+</script>
+
+<div id="viewspace" metal:define-slot="viewspace">
+
+  <h1  i18n:translate=""
+       tal:condition="view/label"
+       tal:content="view/label"
+       metal:define-slot="heading"
+       >Do something</h1>
+
+  <metal:block define-macro="header">
+
+    <div class="form-status"
+       tal:define="status view/status"
+       tal:condition="status">
+
+      <div class="summary"
+           i18n:translate=""
+           tal:content="view/status">
+        Form status summary
+      </div>
+
+      <ul class="errors" tal:condition="view/errors">
+         <li tal:repeat="error view/error_views">
+            <span tal:replace="structure error">Error Type</span>
+         </li>
+      </ul>
+    </div>
+
+  </metal:block>
+
+  <div metal:define-slot="extra_info" tal:replace="nothing">
+  </div>
+
+  <table class="form-fields">
+    <tr class="row" metal:define-slot="extra_top" tal:replace="nothing">
+        <td class="label">Extra top</td>
+        <td class="label"><input type="text" /></td>
+    </tr>
+    <tbody metal:define-slot="formbody" tal:omit-tag="">
+      <tr tal:repeat="widget view/widgets">
+        <td class="label" tal:define="hint widget/hint"
+          metal:define-macro="labelcell">
+          <label tal:condition="python:hint"
+                 tal:attributes="for widget/name"
+                 onmousedown="toggleFormFieldHelp(this,1)"
+                 onmouseup="toggleFormFieldHelp(this,0)"
+                 onmouseout="toggleFormFieldHelp(this,0)"
+                 style="cursor: help">
+            <span class="required" tal:condition="widget/required"
+            >*</span><span i18n:translate=""
+                           tal:content="widget/label">label</span>
+          </label>
+          <label tal:condition="python:not hint"
+                 tal:attributes="for widget/name">
+            <span class="required" tal:condition="widget/required"
+            >*</span><span i18n:translate=""
+                           tal:content="widget/label">label</span>
+          </label>
+        </td>
+        <td class="field" tal:define="hint widget/hint"
+            metal:define-macro="widgetcell">
+          <div class="form-fields-help"
+               i18n:translate=""
+               tal:content="hint"
+               tal:condition="hint"
+               tal:attributes="id string:field-help-for-${widget/name}"
+               onclick="this.style.visibility='hidden';"
+               style="visibility: hidden; position: absolute;"
+               >Title of this content object.</div>
+          <div class="widget" tal:content="structure widget">
+          <input type="text" /></div>
+          <div class="error"
+               tal:condition="widget/error"
+               >
+            <!-- XXX Put this back, the Zope3 way.
+            <img src="alert.gif" alt="Error"
+            tal:replace="structure context/alert.gif" />
+            -->
+            <span tal:replace="structure widget/error">error</span>
+          </div>
+        </td>
+      </tr>
+    </tbody>
+    <tr class="row" metal:define-slot="extra_bottom" tal:replace="nothing">
+      <td class="label">Extra bottom</td>
+      <td class="label"><input type="text" /></td>
+    </tr>
+  </table>
+  <metal:block define-slot="above_buttons" />
+</div>
+<div id="actionsView">
+  <span class="actionButtons"
+        tal:condition="view/availableActions"
+        metal:define-slot="bottom_buttons">
+    <input tal:repeat="action view/actions"
+           tal:replace="structure action/render"
+           />
+  </span>
+</div>
+
+</form>
+<script type="text/javascript" metal:define-slot="trackChanges">
+  zc_trackChanges(document.getElementById('zc.page.browser_form'));
+</script>
+
+<script type="text/javascript"
+    tal:define="extra_script view/extra_script | nothing"
+    tal:condition="extra_script"
+    tal:content="structure extra_script" />
+
+</div>
+
+</div></body></html>

Added: z3lab/cpsblog/trunk/browser/blogform.pt
==============================================================================
--- (empty file)
+++ z3lab/cpsblog/trunk/browser/blogform.pt     Mon Oct 24 07:40:06 2005
@@ -0,0 +1,162 @@
+<html metal:extend-macro="context/@@standard_macros/view"
+      metal:define-macro="main">
+<head>
+<!-- XXX Need test -->
+</head>
+
+<body>
+<div metal:fill-slot="body">
+
+<div metal:define-macro="form">
+
+<form action="." metal:define-macro="master"
+      tal:attributes="action request/URL" method="post"
+      class="edit-form" enctype="multipart/form-data"
+      id="zc.page.browser_form">
+
+<script type="text/javascript"><!--
+
+function toggleFormFieldHelp(ob,state) {
+  // ob is the label element
+  var field = ob.form[ob.htmlFor];
+  if (field) {
+    field.style.visibility = state && 'hidden' || 'visible';
+    var help = document.getElementById("field-help-for-" + field.name);
+    if (help) {
+      help.style.visibility = state && 'visible' || 'hidden';
+    }
+  }
+}
+
+//-->
+</script>
+
+<div id="viewspace" metal:define-slot="viewspace">
+
+  <h1  i18n:translate=""
+       tal:condition="view/label"
+       tal:content="view/label"
+       metal:define-slot="heading"
+       >Do something</h1>
+
+  <metal:block define-macro="header">
+
+    <div class="form-status"
+       tal:define="status view/status"
+       tal:condition="status">
+
+      <div class="summary"
+           i18n:translate=""
+           tal:content="view/status">
+        Form status summary
+      </div>
+
+      <ul class="errors" tal:condition="view/errors">
+         <li tal:repeat="error view/error_views">
+            <span tal:replace="structure error">Error Type</span>
+         </li>
+      </ul>
+    </div>
+
+  </metal:block>
+
+  <div metal:define-slot="extra_info" tal:replace="nothing">
+  </div>
+
+  <table class="form-fields">
+    <tr class="row" metal:define-slot="extra_top" tal:replace="nothing">
+        <td class="label">Extra top</td>
+        <td class="label"><input type="text" /></td>
+    </tr>
+    <tbody metal:define-slot="formbody" tal:omit-tag="">
+      <tr tal:repeat="widget view/widgets">
+        <td class="label" tal:define="hint widget/hint"
+          metal:define-macro="labelcell">
+          <label tal:condition="python:hint"
+                 tal:attributes="for widget/name"
+                 onmousedown="toggleFormFieldHelp(this,1)"
+                 onmouseup="toggleFormFieldHelp(this,0)"
+                 onmouseout="toggleFormFieldHelp(this,0)"
+                 style="cursor: help">
+            <span class="required" tal:condition="widget/required"
+            >*</span><span i18n:translate=""
+                           tal:content="widget/label">label</span>
+          </label>
+          <label tal:condition="python:not hint"
+                 tal:attributes="for widget/name">
+            <span class="required" tal:condition="widget/required"
+            >*</span><span i18n:translate=""
+                           tal:content="widget/label">label</span>
+          </label>
+        </td>
+        <td class="field" tal:define="hint widget/hint"
+            metal:define-macro="widgetcell">
+          <div class="form-fields-help"
+               i18n:translate=""
+               tal:content="hint"
+               tal:condition="hint"
+               tal:attributes="id string:field-help-for-${widget/name}"
+               onclick="this.style.visibility='hidden';"
+               style="visibility: hidden; position: absolute;"
+               >Title of this content object.</div>
+          <div class="widget" tal:content="structure widget">
+          <input type="text" /></div>
+          <div class="error"
+               tal:condition="widget/error"
+               >
+            <!-- XXX Put this back, the Zope3 way.
+            <img src="alert.gif" alt="Error"
+            tal:replace="structure context/alert.gif" />
+            -->
+            <span tal:replace="structure widget/error">error</span>
+          </div>
+        </td>
+      </tr>
+    </tbody>
+    <tr class="row" metal:define-slot="extra_bottom" tal:replace="nothing">
+      <td class="label">Extra bottom</td>
+      <td class="label"><input type="text" /></td>
+    </tr>
+  </table>
+  <metal:block define-slot="above_buttons" />
+</div>
+<div id="actionsView">
+  <span class="actionButtons"
+        tal:condition="view/availableActions"
+        metal:define-slot="bottom_buttons">
+    <input tal:repeat="action view/actions"
+           tal:replace="structure action/render"
+           />
+  </span>
+</div>
+
+</form>
+<script type="text/javascript" metal:define-slot="trackChanges">
+  zc_trackChanges(document.getElementById('zc.page.browser_form'));
+</script>
+
+<script type="text/javascript"
+    tal:define="extra_script view/extra_script | nothing"
+    tal:condition="extra_script"
+    tal:content="structure extra_script" />
+
+</div>
+
+    <div id="sidebar" class="sidebar">
+      <ul id="nav">
+        <li>
+          <a href=""><strong>Blog Actions</strong></a>
+          <ul>
+            <li>
+              <a href="" tal:attributes="href 
string:${context/@@absolute_url}/index.html">View</a>
+            </li>
+            <li>
+              <a href="" tal:attributes="href 
string:${context/@@absolute_url}/edit.html">Edit</a>
+            </li>
+          </ul>
+        </li>
+      </ul>
+    </div>
+
+
+</div></body></html>

Modified: z3lab/cpsblog/trunk/browser/configure.zcml
==============================================================================
--- z3lab/cpsblog/trunk/browser/configure.zcml  (original)
+++ z3lab/cpsblog/trunk/browser/configure.zcml  Mon Oct 24 07:40:06 2005
@@ -1,6 +1,75 @@
 <configure
     xmlns="http://namespaces.zope.org/browser";>
 
+
+  <page
+      name="blogmenu_macros"
+      for="*"
+      class=".macros.BlogMenuMacros"
+      allowed_interface="zope.interface.common.mapping.IItemMapping"
+      permission="zope.Public" />
+
+  <page
+      name="blogmenu_macros_page"
+      for="*"
+      permission="zope.View"
+      template="menu_macros.pt" />
+
+  <menu
+      id="blogmenu"
+      title="Blog Menu"
+      />
+
+  <menuItems
+      menu="blogmenu"
+      for="zope.interface.Interface">
+    <menuItem
+        action="@@index.html"
+        title="View"
+        permission="zope.View"
+        order="3"
+        />
+    <menuItem
+        action="@@edit.html"
+        title="Edit"
+        permission="zope.ManageContent"
+        order="2"
+        />
+    <menuItem
+        action="./+/AddBlogEntry.html"
+        title="Add"
+        permission="zope.ManageContent"
+        order="1"
+        />
+  </menuItems>
+
+
+  <menu
+      id="blogentrymenu"
+      title="Blog Entry Menu"
+      />
+
+  <menuItems
+      menu="blogentrymenu"
+      for="zope.interface.Interface">
+    <menuItem
+        action="@@index.html"
+        title="View"
+        permission="zope.View"
+        />
+    <menuItem
+        action="@@edit.html"
+        title="Edit"
+        permission="zope.ManageContent"
+        />
+    <menuItem
+        action="@@index.html"
+        title="Comments"
+        permission="zope.View"
+        />
+  </menuItems>
+
+
   <!-- Blog -->
 
   <page
@@ -42,7 +111,7 @@
 
   <defaultView
       for="cpsblog.interfaces.IBlog"
-      name="view.html" />
+      name="index.html" />
 
   <icon
       name="zmi_icon"
@@ -75,6 +144,7 @@
       menu="zmi_views" title="Edit" />
 
 
+  <!--
   <page
       name="details.html"
       for="cpsblog.interfaces.IBlogEntry"
@@ -83,10 +153,13 @@
       permission="blog.View"
       menu="zmi_views" title="Preview"
       />
+  -->
 
+  <!--
   <defaultView
       for="cpsblog.interfaces.IBlogEntry"
       name="details.html" />
+  -->
 
   <icon
       name="zmi_icon"
@@ -102,7 +175,7 @@
   <menuItems
       menu="blogentry_actions"
       for="cpsblog.interfaces.IBlogEntry">
-    <menuItem title="View" action="@@details.html" />
+    <!-- <menuItem title="View" action="@@details.html" /> -->
     <menuItem title="Edit" action="@@edit.html" />
   </menuItems>
 
@@ -152,5 +225,6 @@
   </pages>
 
   <include package=".skin" />
+  <include package=".widgets" />
 
 </configure>

Added: z3lab/cpsblog/trunk/browser/macros.py
==============================================================================
--- (empty file)
+++ z3lab/cpsblog/trunk/browser/macros.py       Mon Oct 24 07:40:06 2005
@@ -0,0 +1,6 @@
+# $Id$
+
+from zope.app.basicskin.standardmacros import StandardMacros
+
+class BlogMenuMacros(StandardMacros):
+    macro_pages = ('blogmenu_macros_page', )

Added: z3lab/cpsblog/trunk/browser/menu_macros.pt
==============================================================================
--- (empty file)
+++ z3lab/cpsblog/trunk/browser/menu_macros.pt  Mon Oct 24 07:40:06 2005
@@ -0,0 +1,51 @@
+<metal:block define-macro="mainmenu">
+  <div>
+    <ul>
+      <li tal:repeat="menuitem context/@@view_get_menu/blogmenu">
+        <a href=""
+           tal:attributes="href menuitem/action"
+           tal:content="menuitem/title">
+        </a>
+      </li>
+    </ul>
+  </div>
+</metal:block>
+
+<metal:block define-macro="searchfield">
+  <form id="search" method="post" action="#" title="Search"
+        tal:attributes="action string:${request/URL}">
+    <div>
+      <label for="query" title="Search">
+        Search weblog:
+      </label>
+      <input type="text" id="query" name="query"
+             accesskey="s" size="30" />
+      <input type="submit" id="submit" value="Go" />
+    </div>
+  </form>
+</metal:block>
+
+<metal:block define-macro="entrymenu">
+  <tal:block repeat="menuitem context/@@view_get_menu/blogentrymenu">
+    <a href=""
+       tal:attributes="href string:${item/absolute_url}/${menuitem/action}">
+          <span tal:replace="menuitem/title" />
+          <span tal:condition="not: repeat/menuitem/end"
+                tal:omit-tag="">|</span>
+    </a>
+  </tal:block>
+</metal:block>
+
+
+<metal:block define-macro="entrymainmenu">
+  <div>
+    <ul>
+      <li tal:repeat="menuitem context/@@view_get_menu/blogentrymenu">
+        <a href=""
+           tal:attributes="href menuitem/action"
+           tal:content="menuitem/title">
+        </a>
+      </li>
+    </ul>
+  </div>
+</metal:block>

Added: z3lab/cpsblog/trunk/browser/skin/__init__.py
==============================================================================
--- (empty file)
+++ z3lab/cpsblog/trunk/browser/skin/__init__.py        Mon Oct 24 07:40:06 2005
@@ -0,0 +1 @@
+#
\ No newline at end of file

Added: z3lab/cpsblog/trunk/browser/skin/blog.pt
==============================================================================
--- (empty file)
+++ z3lab/cpsblog/trunk/browser/skin/blog.pt    Mon Oct 24 07:40:06 2005
@@ -0,0 +1,68 @@
+<html metal:use-macro="views/standard_macros/page">
+  <body>
+    <div metal:fill-slot="body">
+        <div class="blog">
+          <h1 tal:content="context/title">Blog Title</h1>
+          <div tal:content="structure context/description" />
+        </div>
+
+        <div>
+          <tal:block condition="exists: request/form/query">
+            <table tal:define="results 
python:view.search(request.form['query'])">
+              <thead>
+                <th>Name</th>
+                <th>Title</th>
+                <th>Description</th>
+              </thead>
+              <tbody>
+                <tal:repeat repeat="item results">
+                  <tr>
+                    <td>
+                      <a href=""
+                         tal:attributes="href item/@@absolute_url"
+                         tal:content="item/title"></a>
+                    </td>
+                    <td tal:content="item/title|nothing" />
+                    <td tal:content="item/description|nothing" />
+                  </tr>
+                </tal:repeat>
+              </tbody>
+            </table>
+          </tal:block>
+
+          <tal:block condition="python: not request.form.has_key('query')">
+            <div tal:repeat="item view/getSortedBlogEntries">
+              <div class="blog-entry">
+                <table border="0" cellpadding="0" cellspacing="0">
+                  <tr>
+                    <td>
+                      <span class="blog-title" tal:content="item/title" />
+                      <span tal:content="structure item/content" />
+                    </td>
+                  </tr>
+                </table>
+                <table border="0" cellpadding="0" cellspacing="0">
+                  <tr>
+                    <td class="blog-footer">
+                      Posted by <span tal:replace="item/author" />
+                      @ <span tal:replace="item/created" />
+                      &nbsp;
+                    </td>
+                    <td align="right" class="blog-footer">
+                      <metal:block 
use-macro="context/@@blogmenu_macros/entrymenu" />
+                    </td>
+                  </tr>
+                </table>
+              </div>
+              <br />
+            </div>
+          </tal:block>
+
+        </div>
+
+      </div>
+
+    <div id="footer" metal:use-macro="footer" />
+
+  </body>
+</html>
\ No newline at end of file

Added: z3lab/cpsblog/trunk/browser/skin/blogentry.pt
==============================================================================
--- (empty file)
+++ z3lab/cpsblog/trunk/browser/skin/blogentry.pt       Mon Oct 24 07:40:06 2005
@@ -0,0 +1,18 @@
+<html metal:use-macro="views/standard_macros/page">
+  <div metal:fill-slot="header">
+    <metal:block use-macro="context/@@blogmenu_macros/entrymainmenu" />
+    <metal:block use-macro="context/@@blogmenu_macros/searchfield" />
+  </div>
+
+  <div metal:fill-slot="body">
+    <h1 tal:content="context/title">Blog entry title</h1>
+    <div class="row" tal:content="structure context/content" />
+    <div class="row" tal:content="structure context/summary" />
+    <div class="row">
+      <span tal:content="view/author" />
+      <span tal:content="view/created" />
+    </div>
+
+  </div>
+
+</html>
\ No newline at end of file

Added: z3lab/cpsblog/trunk/browser/skin/configure.zcml
==============================================================================
--- (empty file)
+++ z3lab/cpsblog/trunk/browser/skin/configure.zcml     Mon Oct 24 07:40:06 2005
@@ -0,0 +1,50 @@
+<configure
+    xmlns="http://namespaces.zope.org/browser";>
+
+  <layer name="blog" />
+  <skin name="blog" layers="blog rotterdam default" />
+
+  <page
+      for="*"
+      name="skin_macros"
+      permission="zope.View"
+      layer="blog"
+      template="template.pt"
+      />
+
+  <page
+      for="cpsblog.interfaces.IBlog"
+      name="index.html"
+      permission="zope.View"
+      layer="blog"
+      template="blog.pt"
+      class="cpsblog.browser.blog.BlogView"
+      />
+
+  <page
+      for="cpsblog.interfaces.IBlogEntry"
+      name="index.html"
+      permission="zope.View"
+      layer="blog"
+      template="blogentry.pt"
+      class="cpsblog.browser.blogentry.BlogEntryView"
+      />
+
+  <resource name="template.css" file="template.css" />
+  <resource name="nuxeo.png" file="images/nuxeo.png" />
+  <resource name="key-point_back.gif" file="images/key-point_back.gif" />
+  <resource name="key-point_tr.gif" file="images/key-point_tr.gif" />
+  <resource name="key-point_tl.gif" file="images/key-point_tl.gif" />
+  <resource name="key-point_br.gif" file="images/key-point_br.gif" />
+  <resource name="key-point_bl.gif" file="images/key-point_bl.gif" />
+  <resource name="body_back.gif" file="images/body_back.gif" />
+  <resource name="header_bl.png" file="images/header_bl.png" />
+  <resource name="header_br.gif" file="images/header_br.gif" />
+  <resource name="header_tab.gif" file="images/header_tab.gif" />
+  <resource name="header_tl.gif" file="images/header_tl.gif" />
+  <resource name="header_tr.gif" file="images/header_tr.gif" />
+  <resource name="menu_back.gif" file="images/menu_back.gif" />
+  <resource name="menu_br.gif" file="images/menu_br.gif" />
+  <resource name="menu_tr.gif" file="images/menu_tr.gif" />
+
+</configure>
\ No newline at end of file

Added: z3lab/cpsblog/trunk/browser/skin/images/body_back.gif
==============================================================================
Binary file. No diff available.

Added: z3lab/cpsblog/trunk/browser/skin/images/header_bl.png
==============================================================================
Binary file. No diff available.

Added: z3lab/cpsblog/trunk/browser/skin/images/header_br.gif
==============================================================================
Binary file. No diff available.

Added: z3lab/cpsblog/trunk/browser/skin/images/header_tab.gif
==============================================================================
Binary file. No diff available.

Added: z3lab/cpsblog/trunk/browser/skin/images/header_tl.gif
==============================================================================
Binary file. No diff available.

Added: z3lab/cpsblog/trunk/browser/skin/images/header_tr.gif
==============================================================================
Binary file. No diff available.

Added: z3lab/cpsblog/trunk/browser/skin/images/key-point_back.gif
==============================================================================
Binary file. No diff available.

Added: z3lab/cpsblog/trunk/browser/skin/images/key-point_bl.gif
==============================================================================
Binary file. No diff available.

Added: z3lab/cpsblog/trunk/browser/skin/images/key-point_br.gif
==============================================================================
Binary file. No diff available.

Added: z3lab/cpsblog/trunk/browser/skin/images/key-point_tl.gif
==============================================================================
Binary file. No diff available.

Added: z3lab/cpsblog/trunk/browser/skin/images/key-point_tr.gif
==============================================================================
Binary file. No diff available.

Added: z3lab/cpsblog/trunk/browser/skin/images/menu_back.gif
==============================================================================
Binary file. No diff available.

Added: z3lab/cpsblog/trunk/browser/skin/images/menu_br.gif
==============================================================================
Binary file. No diff available.

Added: z3lab/cpsblog/trunk/browser/skin/images/menu_tr.gif
==============================================================================
Binary file. No diff available.

Added: z3lab/cpsblog/trunk/browser/skin/images/nuxeo.png
==============================================================================
Binary file. No diff available.

Added: z3lab/cpsblog/trunk/browser/skin/template.css
==============================================================================
--- (empty file)
+++ z3lab/cpsblog/trunk/browser/skin/template.css       Mon Oct 24 07:40:06 2005
@@ -0,0 +1,219 @@
+/* $id$ */
+body {
+    background: #fff url("body_back.gif") repeat-x;
+}
+
+/* Header */
+
+#header {
+    background: #455372 url("header_bl.png") bottom left repeat-x;
+    position: relative;
+    min-heightght: 39px;
+    height: 5em;
+    padding: 0;
+    voice-family: "\"}\"";
+    voice-family: inherit;
+    height: 3em;
+    padding: 15px 0;
+}
+
+#ignored {}
+
+#header h1 {
+    position: absolute;
+    top: 0;
+    left: 0;
+    margin: 0;
+    font-size: 2px;
+    background: url("header_tl.gif") no-repeat;
+    height: 8px;
+    z-index: 100; /* above the UL */
+}
+
+#header h1 a {
+    display: block;
+    width: 204px;
+    height: 55px;
+    background: transparent url("nuxeo.png") no-repeat;
+    text-indent: -700em;
+    text-decoration: none;
+}
+
+#header ul {
+    width: auto;
+    position: absolute;
+    bottom: 0;
+    right: 0;
+    margin: 0;
+    padding: 0 15px 0 0;
+    list-style: none;
+    background: url("header_br.gif") no-repeat bottom right;
+    z-index: 90; /* below the H1 */
+}
+
+#header li {
+    float: right;
+    background: transparent url("header_tab.gif") 100% -600px no-repeat;
+    padding: 0 6px 0 0;
+    margin: 0 1px 0 0;
+    border-bottom: 1px solid #515358;
+}
+
+#header ul a {
+    float: left;
+    display: block;
+    padding: 4px 4px 4px 10px;
+    background: transparent url("header_tab.gif") 0% -600px no-repeat;
+    font-weight: bold;
+    color: #fff;
+    text-decoration: none;
+}
+
+#header ul li:hover a { background-position: 0% -400px; }
+#header ul li:hover { background-position: 100% -400px; }
+
+
+/* Search Field */
+
+#header form {
+    position: absolute;
+    top: 0;
+    right: 0;
+    padding: 12px 20px 0 0;
+    background: url("header_tr.gif") no-repeat top right;
+    margin: 0; /* need for IE Mac */
+    text-align: right; /* need for IE Mac */
+    white-space: nowrap; /* for Opera */
+}
+
+#header form label { color: #fff; font-size: 85%; }
+
+#header form input { font-size: 85%; }
+
+#header form #submit {
+    font-size: 85%;
+    background: #6A7389;
+    color: #fff;
+    padding: 1px 4px;
+    border-right: 1px solid #283043;
+    border-bottom: 1px solid #283043;
+    border-top: 1px solid #9097A2;
+    border-left: 1px solid #9097A2;
+}
+
+#header form #query {
+    width: 170px;
+    font-size: 85%;
+    border:    1px solid #9097A2;
+    background: #D9DBE1;
+    padding: 2px;
+}
+
+#header form #query:hover, #header form #query:focus {
+    background: #fff;
+}
+
+/* Footer */
+
+#footer {
+    border-top: 1px solid #999;
+    margin: 2em 0;
+    padding: 1em 0;
+    text-align: center;
+}
+
+#footer ul {
+    margin: 0;
+    padding: 0;
+    list-style: none;
+}
+
+#footer li {
+    display: inline;
+}
+
+#footer a {
+    white-space: nowrap;
+}
+
+#footer p,#footer p a {
+    color: #666;
+}
+
+#footer p a:hover {
+    color: #000;
+}
+
+#footer p span {
+    padding-right: 1em;
+}
+
+.blog-day {
+    margin-top: 16px;
+    padding: 8px;
+    margin-left: 0px;
+    margin-right: 230px;
+    color: #666;
+}
+
+.blog-footer {
+    font-size: 12px;
+    line-height:2.0em;
+    color: #666;
+}
+
+.blog-entry {
+    margin-left: 0px;
+    margin-right: 230px;
+    padding: 8px;
+    border: 1px solid #ccc;
+}
+
+.blog-title {
+    margin-top: 16px;
+    margin-left: 0px;
+    margin-right: 0px;
+    font-size: 14pt;
+    font-weight: bold;
+    line-height: 2.0em;
+}
+
+.blog-entry-comment {
+    margin-left: 0px;
+    margin-right: 250px;
+    width: 480px;
+    padding: 8px;
+    border: 1px solid #ccc;
+}
+
+
+.blog {
+    background: #e4ecec url("key-point_back.gif") right repeat-y;
+    padding: 15px;
+    margin-bottom: 1em;
+    margin-left: 0px;
+    margin-right: 230px;
+}
+
+.blog:before {
+    line-height: 0.1;
+    font-size: 1px;
+    background: transparent url("key-point_tr.gif") no-repeat top right;
+    margin: -15px -15px 0 -15px;
+    height: 15px;
+    display: block;
+    border: none;
+    content: url("key-point_tl.gif");
+}
+
+.blog:after {
+    display: block;
+    clear: both;
+    padding-top: 15px;
+    line-height: 0.1;
+    font-size: 1px;
+    content:  url("key-point_bl.gif");
+    margin: -15px;
+    height: 8px;
+    background: transparent url("key-point_br.gif") scroll no-repeat bottom 
right ;
+}
\ No newline at end of file

Added: z3lab/cpsblog/trunk/browser/skin/template.pt
==============================================================================
--- (empty file)
+++ z3lab/cpsblog/trunk/browser/skin/template.pt        Mon Oct 24 07:40:06 2005
@@ -0,0 +1,82 @@
+<metal:block define-macro="page">
+  <metal:block define-slot="doctype">
+    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd";>
+  </metal:block>
+
+<html xmlns="http://www.w3.org/1999/xhtml";
+      xml:lang="en"
+      lang="en"
+      i18n:domain="blog">
+
+  <head>
+    <title metal:define-slot="title">Blog</title>
+
+    <style type="text/css" media="all"
+           tal:content="string:@import 
url(${context/++resource++template.css});">
+      @import url(zope3.css);
+    </style>
+
+    <tal:block condition="python:request['PATH_INFO'].endswith('.html')">
+      <script type="text/javascript"
+              tal:define="fckeditorurl string:'${request/URL/0}/@@/fckeditor/';
+                          configurl string:'${request/URL/0}/@@/myconfig.js';"
+              tal:content="string:
+                           fckBasePath=${fckeditorurl};
+                           configURL=${configurl};">
+      </script>
+      <script type="text/javascript" src="#"
+              tal:attributes="src
+                              
string:${context/++resource++fckeditor/fckeditor.js}">
+      </script>
+    </tal:block>
+
+    <meta http-equiv="Content-Type"
+          content="text/html;charset=utf-8" />
+
+    <link rel="icon" type="image/png"
+          tal:attributes="href context/++resource++favicon.png" />
+  </head>
+
+  <body>
+
+    <div id="header">
+      <h1>
+        <a href=""
+           tal:attributes="href 
string:${context/@@absolute_url}/++site++">logo</a>
+      </h1>
+      <metal:block define-slot="header">
+        <metal:block use-macro="context/@@blogmenu_macros/mainmenu" />
+        <metal:block use-macro="context/@@blogmenu_macros/searchfield" />
+      </metal:block>
+    </div>
+
+    <div id="breadcrumbs" metal:define-macro="breadcrumbs">
+      <span tal:omit-tag="" i18n:translate="">Location:&nbsp;</span>
+      <tal:block repeat="breadcrumb context/@@absolute_url/breadcrumbs">
+        <tal:block condition="python: not path('repeat/breadcrumb/end') and 
not path('repeat/breadcrumb/start')">
+          /<a href=""
+             tal:content="string:${breadcrumb/name}"
+             tal:attributes="href string:${breadcrumb/url}">breadcrumb item</a>
+        </tal:block>
+      </tal:block>
+    </div>
+
+
+    <div id="workspace" metal:define-macro="workspace">
+      <div metal:define-slot="entry" id="entry"></div>
+
+      <div>
+        <metal:block define-slot="body">
+          This is the content
+        </metal:block>
+      </div>
+    </div>
+
+    <div id="footer" metal:define-macro="footer" />
+
+  </body>
+
+</html>
+
+</metal:block>

Added: z3lab/cpsblog/trunk/browser/widgets/__init__.py
==============================================================================
--- (empty file)
+++ z3lab/cpsblog/trunk/browser/widgets/__init__.py     Mon Oct 24 07:40:06 2005
@@ -0,0 +1,31 @@
+# $Id$
+from zope.app.form.browser.widget import SimpleInputWidget
+from zope.app.form.browser.widget import renderElement
+
+class FCKEditorWidget(SimpleInputWidget):
+
+    style = ''
+
+    def __call__(self):
+        name = self.name
+        # field name without prefix
+        field_name = name[len(self._prefix):]
+
+        code = "var oFCKeditor_%s=new FCKeditor('%s');" % (field_name, name)
+        code += "oFCKeditor_%s.BasePath=fckBasePath;" % field_name
+        code += "oFCKeditor_%s.Width=800;" % field_name
+        code += "oFCKeditor_%s.Height=400;" % field_name
+        code += "oFCKeditor_%s.Config['CustomConfigurationsPath']=%s;" \
+                 % (field_name, 'configURL')
+        code += "oFCKeditor_%s.ReplaceTextarea();" % field_name
+
+        script = "<script type='%s' language='%s'>%s</script>" \
+                 % ('text/javascript', 'JavaScript', code)
+
+        textarea = renderElement('textarea',
+                                 name=self.name,
+                                 id=self.name,
+                                 style=self.style,
+                                 contents=self._getFormValue(),
+                                 )
+        return textarea + script

Added: z3lab/cpsblog/trunk/browser/widgets/configure.zcml
==============================================================================
--- (empty file)
+++ z3lab/cpsblog/trunk/browser/widgets/configure.zcml  Mon Oct 24 07:40:06 2005
@@ -0,0 +1,15 @@
+<configure
+    xmlns:zope="http://namespaces.zope.org/zope";
+    xmlns="http://namespaces.zope.org/browser";>
+
+  <resourceDirectory
+      name="fckeditor"
+      directory="fckeditor"
+      />
+
+  <resource
+      name="myconfig.js"
+      file="myconfig.js"
+      />
+
+</configure>

Added: z3lab/cpsblog/trunk/browser/widgets/myconfig.js
==============================================================================
--- (empty file)
+++ z3lab/cpsblog/trunk/browser/widgets/myconfig.js     Mon Oct 24 07:40:06 2005
@@ -0,0 +1,2 @@
+FCKConfig.Width = 900;
+FCKConfig.EditorAreaCSS = FCKConfig.BasePath + 'css/fck_editorarea.css';
\ No newline at end of file

Modified: z3lab/cpsblog/trunk/configure.zcml
==============================================================================
--- z3lab/cpsblog/trunk/configure.zcml  (original)
+++ z3lab/cpsblog/trunk/configure.zcml  Mon Oct 24 07:40:06 2005
@@ -167,6 +167,18 @@
       permission="zope.Public"
       />
 
+  <adapter
+      name="site"
+      provides="zope.app.traversing.interfaces.ITraversable" for="*"
+      factory=".adapters.Site" />
+
+  <view
+      name="site"
+      type="*"
+      provides="zope.app.traversing.interfaces.ITraversable" for="*"
+      factory=".adapters.Site"
+      />
+
   <include package=".browser" />
   <include package=".catalog" />
 
-- 
http://lists.nuxeo.com/mailman/listinfo/z3lab-checkins

Reply via email to