1
2
3
4
5
6
7
8
9
10
11 """
12 The is the base renderer module. If you were to dislike the blosxom
13 renderer and wanted to build a renderer that used a different templating
14 system, you would extend the RendererBase class and implement the
15 functionality required by the other rendering system.
16
17 For examples, look at the BlosxomRenderer and the Renderer in the debug
18 module.
19 """
20
21 __revision__ = "$Revision: 1043 $"
22
23 import sys
24 import time
25
27 """
28 Basic Renderer:
29 - Pyblosxom Core handles the Input and Process of the system and passes
30 the result of the process to the Renderers for output. All renderers
31 are child classes of RendererBase. RenderBase will contain the public
32 interfaces for all Renderer onject.
33 """
34
35 - def __init__(self, request, stdoutput = sys.stdout):
36 """
37 Constructor: Initializes the Renderer
38
39 @param request: The L{Pyblosxom.pyblosxom.Request} object
40 @type request: L{Pyblosxom.pyblosxom.Request} object
41 @param stdoutput: File like object to print to.
42 @type stdoutput: file
43 """
44 self._request = request
45
46
47 self._header = []
48
49 self._out = stdoutput
50 self._content = None
51 self._content_mtime = None
52 self._needs_content_type = 1
53 self.rendered = None
54
55
57 """
58 Convenience method for programs to use instead of accessing
59 self._out.write()
60
61 Other classes can override this if there is a unique way to
62 write out data, for example, a two stream output, e.g. one
63 output stream and one output log stream.
64
65 Another use for this could be a plugin that writes out binary
66 files, but because renderers and other frameworks may probably
67 not want you to write to C{stdout} directly, this method assists
68 you nicely. For example::
69
70 def cb_start(args):
71 req = args['request']
72 renderer = req['renderer']
73
74 if reqIsGif and gifFileExists(theGifFile):
75 # Read the file
76 data = open(theGifFile).read()
77
78 # Modify header
79 renderer.addHeader('Content-type', 'image/gif')
80 renderer.addHeader('Content-Length', len(data))
81 renderer.showHeaders()
82
83 # Write to output
84 renderer.write(data)
85
86 # Tell pyblosxom not to render anymore as data is
87 # processed already
88 renderer.rendered = 1
89
90 This simple piece of pseudocode explains what you could do with
91 this method, though I highly don't recommend this, unless
92 pyblosxom is running continuously.
93
94 @param data: Piece of string you want printed
95 @type data: string
96 """
97 self._out.write(data)
98
99
101 """
102 Populates the HTTP header with lines of text
103
104 @param args: Paired list of headers
105 @type args: argument lists
106 @raises ValueError: This happens when the parameters are not correct
107 """
108 args = list(args)
109 if len(args) % 2 != 0:
110 raise ValueError, 'Headers recieved are not in the correct form'
111
112 while args:
113 key = args.pop(0).strip()
114 if key.find(' ') != -1 or key.find(':') != -1:
115 raise ValueError, 'There should be no spaces in header keys'
116 value = args.pop(0).strip()
117 self._header.append( (key, value) )
118
119 - def setContent(self, content):
120 """
121 Sets the content
122
123 @param content: What content are we to show?
124 @type content: C{list} List of entries to process or C{dict} Simple
125 dict containing at least 'title' and 'body'
126 """
127 self._content = content
128 if isinstance(self._content, dict):
129 mtime = self._content.get("mtime", time.time())
130 elif isinstance(self._content, list):
131 mtime = self._content[0].get("mtime", time.time())
132 else:
133 mtime = time.time()
134 self._content_mtime = mtime
135
136
137 - def needsContentType(self, flag):
138 """
139 Use the renderer to determine 'Content-Type: x/x' default is to use the
140 renderer for Content-Type, set flag to None to indicate no Content-Type
141 generation.
142
143 @param flag: True of false value
144 """
145 self._needs_content_type = flag
146
147
149 """
150 Updated the headers of the L{Response<Pyblosxom.pyblosxom.Response>}
151 instance.
152 This is just for backwards compatibility.
153 """
154 response = self._request.getResponse()
155 for k, v in self._header:
156 response.addHeader(k, v)
157
158
159 - def render(self, header = 1):
160 """
161 Do final rendering.
162
163 @param header: Do we want to show headers?
164 @type header: boolean
165 """
166 if header:
167 if self._header:
168 self.showHeaders()
169 else:
170 self.addHeader('Content-Type', 'text/plain')
171 self.showHeaders()
172
173 if self._content:
174 self.write(self._content)
175 self.rendered = 1
176
178 """
179 This is a null renderer.
180 """
181 pass
182