Explorar el Código

head and body tags of landing page exposed as ElementTree.Elements

Darren Ranalli hace 16 años
padre
commit
3b0682d19f
Se han modificado 3 ficheros con 146 adiciones y 53 borrados
  1. 52 17
      direct/src/http/LandingPage.py
  2. 73 3
      direct/src/http/LandingPageHTML.py
  3. 21 33
      direct/src/http/WebRequest.py

+ 52 - 17
direct/src/http/LandingPage.py

@@ -13,9 +13,6 @@ class LandingPage:
         self.headerTemplate = LandingPageHTML.header
         self.footerTemplate = LandingPageHTML.footer
 
-        # allow modifications to the page head tag
-        self._headET = ET.Element('head')
-        
         self.menu = {}
 
         self.uriToTitle = {}
@@ -51,20 +48,58 @@ class LandingPage:
     def getMenu(self, activeTab):
         return LandingPageHTML.getTabs(self.menu,activeTab)
 
-    def getHeader(self, activeTab = "Main"):
-        headContent = ''
-        for child in self._headET.getchildren():
-            fileStr = StringIO()
-            ET.ElementTree(child).write(fileStr)
-            headContent += fileStr.getvalue()
-        s = self.headerTemplate % {'titlestring' : LandingPageHTML.title,
-                                   'menustring' : self.getMenu(activeTab),
-                                   'headContent' : headContent,}
+    def getMenuTags(self, activeTab):
+        return LandingPageHTML.getTabTags(self.menu, activeTab)
+
+    def getHeader(self, activeTab = "Main", headTag=None, bodyTag=None):
+        if headTag is None:
+            headTag = ET.Element('head')
+        if bodyTag is None:
+            bodyTag = ET.Element('body')
+
+        # make sure each component has elements to make formatting consistent
+        headTag.append(ET.Comment(''))
+        bodyTag.append(ET.Comment(''))
+
+        fileStr = StringIO()
+        ET.ElementTree(headTag).write(fileStr)
+        headTagStr = fileStr.getvalue()
+        # remove the tag closer
+        # </head>
+        headTagStr = headTagStr[:headTagStr.rindex('<')]
+
+        # fill in the prefab body tag content
+        titleStr = LandingPageHTML.title
+        landing = ET.Element('body')
+        LandingPageHTML.addBodyHeaderAndContent(landing, titleStr, self.getMenuTags(activeTab))
+
+        fileStr = StringIO()
+        ET.ElementTree(landing).write(fileStr)
+        landingStr = fileStr.getvalue()
+        # remove <body>
+        landingStr = landingStr[landingStr.index('>')+1:]
+        # remove tag closers
+        for i in xrange(3):
+            # </body>
+            # contents </div>
+            # </center>
+            landingStr = landingStr[:landingStr.rindex('<')]
+        
+        fileStr = StringIO()
+        ET.ElementTree(bodyTag).write(fileStr)
+        bodyTagStr = fileStr.getvalue()
+        # extract <body>
+        bodyStr = bodyTagStr[bodyTagStr.index('>')+1:]
+        bodyTagStr = bodyTagStr[:bodyTagStr.index('>')+1]
+
+        bodyStr = bodyTagStr + '\n' + landingStr + '\n' + bodyStr
+
+        s = self.headerTemplate % {'titlestring': titleStr,
+                                   'headTag' : headTagStr,
+                                   'bodyTag': bodyStr,
+                                   }
         return s
 
-    def getHead(self):
-        return self._headET
-
     def getFooter(self):
         return self.footerTemplate % {'contact' : LandingPageHTML.contactInfo}
 
@@ -130,9 +165,9 @@ class LandingPage:
     def getFavIcon(self):
         return self.favicon
     
-    def skin(self, body, uri):
+    def skin(self, body, uri, headTag=None, bodyTag=None):
         title = self.uriToTitle.get(uri,"Services")
-        return self.getHeader(title) + body + self.getFooter()
+        return self.getHeader(title, headTag, bodyTag) + body + self.getFooter()
 
     def addQuickStat(self,item,value,position):
         if item in self.quickStats[1]:

+ 73 - 3
direct/src/http/LandingPageHTML.py

@@ -1,5 +1,7 @@
 # -- Text content for the landing page.  You should change these for yours! --
 
+from direct.showbase import ElementTree as ET
+
 title = "Landing Page"
 defaultTitle = title
 
@@ -258,14 +260,17 @@ stylesheet = '''
 
 header = '''
 <html>
-<head>
+%(headTag)s
 <title>%(titlestring)s</title>
 <link rel="stylesheet" type="text/css" href="/default.css">
-%(headContent)s
 </head>
 
-<body>
+%(bodyTag)s
+'''
 
+# this portion of the body is now added dynamically in order to support changes to the body tag
+# attributes
+'''
 <!-- HEADER -->
 
 <div id="header">
@@ -280,8 +285,26 @@ header = '''
 
 <div id="contents">
 <center>
+
 '''
 
+# caller must remove '</div>' from end of output string derived from what is returned
+def addBodyHeaderAndContent(bodyTag, titleString, menuTags):
+    SE = ET.SubElement
+    bodyTag.append(ET.Comment('HEADER'))
+    header = SE(bodyTag, 'div', id='header')
+    h2 = SE(header, 'h2')
+    h2.text = titleString
+    navContainer = SE(header, 'div', id='navcontainer')
+    navList = SE(navContainer, 'ul', id='navlist')
+    for menuTag in menuTags:
+        navList.append(menuTag)
+    bodyTag.append(ET.Comment('CONTENT'))
+    contents = SE(bodyTag, 'div', id='contents')
+    center = SE(contents, 'center')
+    # for ease of removal of center tag closer
+    center.append(ET.Comment(''))
+
 mainPageBody = '''
 <P>%(description)s</P>
 
@@ -363,6 +386,53 @@ def getTabs(menu,activeTab):
 
     return s    
 
+def getTabTags(menu,activeTab):
+    tabList = menu.keys()
+    if "Main" in tabList:
+        tabList.remove("Main")
+    if "Services" in tabList:
+        tabList.remove("Services")
+        
+    tabList.sort()
+    
+    if "Main" in menu.keys():
+        tabList.insert(0, "Main")
+    if "Services" in menu.keys():
+        tabList.insert(1, "Services")
+
+    tabNum = 0
+
+    tags = []
+
+    for tab in tabList:
+        if tabNum == 0:
+            if tab == activeTab:
+                li = ET.Element('li', id='active')
+                li.set('class', 'first')
+                a = ET.SubElement(li, 'a', href=menu[tab], id='current')
+                a.text = tab
+                tags.append(li)
+            else:
+                li = ET.Element('li')
+                li.set('class', 'first')
+                a = ET.SubElement(li, 'a', href=menu[tab])
+                a.text = tab
+                tags.append(li)
+        else:
+            if tab == activeTab:
+                li = ET.Element('li', id='active')
+                a = ET.SubElement(li, 'a', href=menu[tab], id='current')
+                a.text = tab
+                tags.append(li)
+            else:
+                li = ET.Element('li')
+                a = ET.SubElement(li, 'a', href=menu[tab])
+                a.text = tab
+                tags.append(li)
+        tabNum += 1
+
+    return tags
+
 def getQuickStatsTable(quickStats):
     output = "\n<table>\n<caption>Quick Stats</caption>\n<thead><tr><th scope=col>Item</th><th scope=col>Value</th></tr></thead>\n"
     output += "<tbody>\n"

+ 21 - 33
direct/src/http/WebRequest.py

@@ -69,31 +69,23 @@ class SkinningReplyTo:
         self._dispatcher = dispatcher
         self._uri = uri
         self._doSkin = doSkin
-        self._headTags = self._dispatcher._headTags[:]
-        self._dispatcher._clearHeadTags()
+        self._headTag = ET.Element('head')
+        self._bodyTag = ET.Element('body')
 
     def respondHTTP(self,status,body):
         if self._doSkin:
-            self._addHeadTags()
-            body = self._dispatcher.landingPage.skin(body, self._uri)
-            self._removeHeadTags()
+            body = self._dispatcher.landingPage.skin(
+                body, self._uri, headTag=self._headTag, bodyTag=self._bodyTag)
         self._replyTo.respondHTTP(status, body)
 
     def respond(self, response):
         self.respondHTTP("200 OK", response)
 
-    def addTagToHead(self, tag):
-        self._headTags.append(tag)
-
-    def _addHeadTags(self):
-        head = self._dispatcher.landingPage.getHead()
-        for tag in self._headTags:
-            head.append(tag)
-
-    def _removeHeadTags(self):
-        head = self._dispatcher.landingPage.getHead()
-        for tag in self._headTags:
-            head.remove(tag)
+    # provides access to head and body tags of landing page
+    def getHeadTag(self):
+        return self._headTag
+    def getBodyTag(self):
+        return self._bodyTag
 
     def __getattr__(self, attrName):
         if attrName in self.__dict__:
@@ -142,7 +134,6 @@ class WebRequestDispatcher(object):
 
     def __init__(self, wantLandingPage = True):
         self.enableLandingPage(wantLandingPage)
-        self._headTags = []
 
     def listenOnPort(self,listenPort):
         """
@@ -161,6 +152,13 @@ class WebRequestDispatcher(object):
         replyTo.respondHTTP("404 Not Found",resp)
         self.notify.warning("%s - %s - 404" % (replyTo.getSourceAddress(),replyTo.getURI()))
 
+    # access to head and body tags of landing page
+    # only for 'returnsResponse' mode
+    def getHeadTag(self):
+        return self._headTag
+    def getBodyTag(self):
+        return self._bodyTag
+
     def handleGET(self,req):
         """
         Parse and dispatch a single GET request.
@@ -181,27 +179,17 @@ class WebRequestDispatcher(object):
         if returnsResponse:
             result = apply(callable,(),args)
             if autoSkin:
-                req.respond(self.landingPage.skin(result,uri))
+                self._headTag = ET.Element('head')
+                self._bodyTag = ET.Element('body')
+                req.respond(self.landingPage.skin(result,uri, headTag=self._headTag, bodyTag=self._bodyTag))
+                del self._bodyTag
+                del self._headTag
             else:
                 req.respond(result)
-            self._clearHeadTags()
         else:
             args["replyTo"] = SkinningReplyTo(req, self, uri, autoSkin)
             apply(callable,(),args)
 
-    def addTagToHead(self, tag):
-        # adds a sub-tag within the head tag for the next outgoing response in returnsResponse mode
-        # for non-returnsResponse mode, use API on SkinningReplyTo
-        head = self.landingPage.getHead()
-        head.append(tag)
-        self._headTags.append(tag)
-
-    def _clearHeadTags(self):
-        head = self.landingPage.getHead()
-        for tag in self._headTags:
-            head.remove(tag)
-        self._headTags = []
-
     def poll(self):
         """
         Pump the web server, handle any incoming requests.