12 ] |
12 ] |
13 |
13 |
14 Why does not CubicWeb have a template language ? |
14 Why does not CubicWeb have a template language ? |
15 ------------------------------------------------ |
15 ------------------------------------------------ |
16 |
16 |
17 There are enough template languages out there. You can use your |
17 There are enough template languages out there. You can use your |
18 preferred template language if you want. [explain how to use a |
18 preferred template language if you want. [explain how to use a |
19 template language] |
19 template language] |
20 |
20 |
21 *CubicWeb* does not define its own templating language as this was |
21 *CubicWeb* does not define its own templating language as this was |
22 not our goal. Based on our experience, we realized that |
22 not our goal. Based on our experience, we realized that |
23 we could gain productivity by letting designers use design tools |
23 we could gain productivity by letting designers use design tools |
24 and developpers develop without the use of the templating language |
24 and developpers develop without the use of the templating language |
25 as an intermediary that could not be anyway efficient for both parties. |
25 as an intermediary that could not be anyway efficient for both parties. |
26 Python is the templating language that we use in *CubicWeb*, but again, |
26 Python is the templating language that we use in *CubicWeb*, but again, |
27 it does not prevent you from using a templating language. |
27 it does not prevent you from using a templating language. |
28 |
28 |
29 The reason template languages are not used in this book is that |
29 The reason template languages are not used in this book is that |
30 experience has proved us that using pure python was less cumbersome. |
30 experience has proved us that using pure python was less cumbersome. |
31 |
31 |
32 Why do you think using pure python is better than using a template language ? |
32 Why do you think using pure python is better than using a template language ? |
33 ----------------------------------------------------------------------------- |
33 ----------------------------------------------------------------------------- |
34 |
34 |
35 Python is an Object Oriented Programming language and as such it |
35 Python is an Object Oriented Programming language and as such it |
36 already provides a consistent and strong architecture and syntax |
36 already provides a consistent and strong architecture and syntax |
37 a templating language would not reach. |
37 a templating language would not reach. |
38 |
38 |
39 When doing development, you need a real language and template |
39 When doing development, you need a real language and template |
40 languages are not real languages. |
40 languages are not real languages. |
41 |
41 |
42 Using Python instead of a template langage for describing the user interface |
42 Using Python instead of a template langage for describing the user interface |
43 makes it to maintain with real functions/classes/contexts without the need of |
43 makes it to maintain with real functions/classes/contexts without the need of |
44 learning a new dialect. By using Python, we use standard OOP techniques and |
44 learning a new dialect. By using Python, we use standard OOP techniques and |
45 this is a key factor in a robust application. |
45 this is a key factor in a robust application. |
46 |
46 |
47 Why do you use the LGPL license to prevent me from doing X ? |
47 Why do you use the LGPL license to prevent me from doing X ? |
48 ------------------------------------------------------------ |
48 ------------------------------------------------------------ |
49 |
49 |
50 LGPL means that *if* you redistribute your application, you need to |
50 LGPL means that *if* you redistribute your application, you need to |
51 redistribute the changes you made to CubicWeb under the LGPL licence. |
51 redistribute the changes you made to CubicWeb under the LGPL licence. |
52 |
52 |
53 Publishing a web site has nothing to do with redistributing |
53 Publishing a web site has nothing to do with redistributing |
54 source code. A fair amount of companies use modified LGPL code |
54 source code. A fair amount of companies use modified LGPL code |
55 for internal use. And someone could publish a *CubicWeb* component |
55 for internal use. And someone could publish a *CubicWeb* component |
56 under a BSD licence for others to plug into a LGPL framework without |
56 under a BSD licence for others to plug into a LGPL framework without |
57 any problem. The only thing we are trying to prevent here is someone |
57 any problem. The only thing we are trying to prevent here is someone |
58 taking the framework and packaging it as closed source to his own |
58 taking the framework and packaging it as closed source to his own |
59 clients. |
59 clients. |
60 |
60 |
61 |
61 |
62 CubicWeb looks pretty recent. Is it stable ? |
62 CubicWeb looks pretty recent. Is it stable ? |
63 -------------------------------------------- |
63 -------------------------------------------- |
64 |
64 |
65 It is constantly evolving, piece by piece. The framework has evolved since |
65 It is constantly evolving, piece by piece. The framework has evolved since |
66 2001 and data has been migrated from one schema to the other ever since. There |
66 2001 and data has been migrated from one schema to the other ever since. There |
67 is a well-defined way to handle data and schema migration. |
67 is a well-defined way to handle data and schema migration. |
68 |
68 |
69 Why is the RQL query language looking similar to X ? |
69 Why is the RQL query language looking similar to X ? |
70 ----------------------------------------------------- |
70 ----------------------------------------------------- |
71 |
71 |
72 It may remind you of SQL but it is higher level than SQL, more like |
72 It may remind you of SQL but it is higher level than SQL, more like |
73 SPARQL. Except that SPARQL did not exist when we started the project. |
73 SPARQL. Except that SPARQL did not exist when we started the project. |
74 Having SPARQL as a query language has been in our backlog for years. |
74 With version 3.4, CubicWeb has support for SPARQL. |
75 |
75 |
76 That RQL language is what is going to make a difference with django- |
76 That RQL language is what is going to make a difference with django- |
77 like frameworks for several reasons. |
77 like frameworks for several reasons. |
78 |
78 |
79 1. accessing data is *much* easier with it. One can write complex |
79 1. accessing data is *much* easier with it. One can write complex |
80 queries with RQL that would be tedious to define and hard to maintain |
80 queries with RQL that would be tedious to define and hard to maintain |
81 using an object/filter suite of method calls. |
81 using an object/filter suite of method calls. |
82 |
82 |
83 2. it offers an abstraction layer allowing your applications to run |
83 2. it offers an abstraction layer allowing your applications to run |
84 on multiple back-ends. That means not only various SQL backends |
84 on multiple back-ends. That means not only various SQL backends |
85 (postgresql, sqlite, mysql), but also multiple databases at the |
85 (postgresql, sqlite, mysql), but also multiple databases at the |
86 same time, and also non-SQL data stores like LDAP directories and |
86 same time, and also non-SQL data stores like LDAP directories and |
87 subversion/mercurial repositories (see the `vcsfile` |
87 subversion/mercurial repositories (see the `vcsfile` |
88 component). Google App Engine is yet another supported target for |
88 component). Google App Engine is yet another supported target for |
89 RQL. |
89 RQL. |
90 |
90 |
91 [copy answer from forum, explain why similar to sparql and why better |
91 [copy answer from forum, explain why similar to sparql and why better |
92 than django and SQL] |
92 than django and SQL] |
93 |
93 |
94 which ajax library is CubicWeb using ? |
94 which ajax library is CubicWeb using ? |
98 |
98 |
99 |
99 |
100 How is security implemented ? |
100 How is security implemented ? |
101 ------------------------------ |
101 ------------------------------ |
102 |
102 |
103 This is an example of how it works in our framework:: |
103 This is an example of how it works in our framework: |
|
104 |
|
105 .. sourcecode:: python |
104 |
106 |
105 class Version(EntityType): |
107 class Version(EntityType): |
106 """a version is defining the content of a particular project's |
108 """a version is defining the content of a particular project's |
107 release""" |
109 release""" |
108 # definition of attributes is voluntarily missing |
110 # definition of attributes is voluntarily missing |
109 permissions = {'read': ('managers', 'users', 'guests',), |
111 permissions = {'read': ('managers', 'users', 'guests',), |
110 'update': ('managers', 'logilab', 'owners',), |
112 'update': ('managers', 'logilab', 'owners',), |
111 'delete': ('managers', ), |
113 'delete': ('managers', ), |
112 'add': ('managers', 'logilab', |
114 'add': ('managers', 'logilab', |
113 ERQLExpression('X version_of PROJ, U in_group G, ' |
115 ERQLExpression('X version_of PROJ, U in_group G, ' |
114 'PROJ require_permission P, ' |
116 'PROJ require_permission P, ' |
115 'P name "add_version", P require_group G'),)} |
117 'P name "add_version", P require_group G'),)} |
116 |
118 |
117 The above means that permission to read a Version is granted to any |
119 The above means that permission to read a Version is granted to any |
118 user that is part of one of the groups 'managers', 'users', 'guests'. |
120 user that is part of one of the groups 'managers', 'users', 'guests'. |
119 The 'add' permission is granted to users in group 'managers' or |
121 The 'add' permission is granted to users in group 'managers' or |
120 'logilab' and to users in group G, if G is linked by a permission |
122 'logilab' and to users in group G, if G is linked by a permission |
121 entity named "add_version" to the version's project. |
123 entity named "add_version" to the version's project. |
122 :: |
124 |
|
125 .. sourcecode:: python |
123 |
126 |
124 class version_of(RelationType): |
127 class version_of(RelationType): |
125 """link a version to its project. A version is necessarily linked |
128 """link a version to its project. A version is necessarily linked |
126 to one and only one project. """ |
129 to one and only one project. """ |
127 # some lines voluntarily missing |
130 # some lines voluntarily missing |
128 permissions = {'read': ('managers', 'users', 'guests',), |
131 permissions = {'read': ('managers', 'users', 'guests',), |
129 'delete': ('managers', ), |
132 'delete': ('managers', ), |
130 'add': ('managers', 'logilab', |
133 'add': ('managers', 'logilab', |
131 RRQLExpression('O require_permission P, P name "add_version", |
134 RRQLExpression('O require_permission P, P name "add_version", ' |
132 'U in_group G, P require_group G'),) } |
135 'U in_group G, P require_group G'),) } |
133 |
136 |
134 You can find additional information in the section :ref:`security`. |
137 You can find additional information in the section :ref:`security`. |
135 |
138 |
136 [XXX what does the second example means in addition to the first one?] |
139 [XXX what does the second example means in addition to the first one?] |
137 |
140 |
138 |
141 |
139 What is `Error while publishing rest text ...` ? |
142 What is `Error while publishing rest text ...` ? |
140 ------------------------------------------------ |
143 ------------------------------------------------ |
141 |
144 |
142 While modifying the description of an entity, you get an error message in |
145 While modifying the description of an entity, you get an error message in |
143 the instance `Error while publishing ...` for Rest text and plain text. |
146 the instance `Error while publishing ...` for Rest text and plain text. |
144 The server returns a traceback like as follows :: |
147 The server returns a traceback like as follows :: |
145 |
148 |
146 2008-10-06 15:05:08 - (cubicweb.rest) ERROR: error while publishing ReST text |
149 2008-10-06 15:05:08 - (cubicweb.rest) ERROR: error while publishing ReST text |
147 Traceback (most recent call last): |
150 Traceback (most recent call last): |
148 File "/home/user/src/blogdemo/cubicweb/common/rest.py", line 217, in rest_publish |
151 File "/home/user/src/blogdemo/cubicweb/common/rest.py", line 217, in rest_publish |
149 File "/usr/lib/python2.5/codecs.py", line 817, in open |
152 File "/usr/lib/python2.5/codecs.py", line 817, in open |
150 file = __builtin__.open(filename, mode, buffering) |
153 file = __builtin__.open(filename, mode, buffering) |
151 TypeError: __init__() takes at most 3 arguments (4 given) |
154 TypeError: __init__() takes at most 3 arguments (4 given) |
152 |
155 |
153 |
156 This can be fixed by applying the patch described in : |
154 This can be fixed by applying the patch described in : |
157 http://code.google.com/p/googleappengine/issues/detail?id=48 |
155 http://code.google.com/p/googleappengine/issues/detail?id=48 |
|
156 |
158 |
157 What are hooks used for ? |
159 What are hooks used for ? |
158 ------------------------- |
160 ------------------------- |
159 |
161 |
160 Hooks are executed around (actually before or after) events. The |
162 Hooks are executed around (actually before or after) events. The |
161 most common events are data creation, update and deletion. They |
163 most common events are data creation, update and deletion. They |
162 permit additional constraint checking (those not expressible at the |
164 permit additional constraint checking (those not expressible at the |
163 schema level), pre and post computations depending on data |
165 schema level), pre and post computations depending on data |
164 movements. |
166 movements. |
165 |
167 |
166 As such, they are a vital part of the framework. |
168 As such, they are a vital part of the framework. |
167 |
169 |
168 Other kinds of hooks, called Operations, are available |
170 Other kinds of hooks, called Operations, are available |
169 for execution just before commit. |
171 for execution just before commit. |
170 |
172 |
171 When should you define an HTML template rather than define a graphical component ? |
173 When should you define an HTML template rather than define a graphical component ? |
172 ---------------------------------------------------------------------------------- |
174 ---------------------------------------------------------------------------------- |
173 |
175 |
174 An HTML template cannot contain code, hence it is only about static |
176 An HTML template cannot contain code, hence it is only about static |
175 content. A component is made of code and operations that apply on a |
177 content. A component is made of code and operations that apply on a |
176 well defined context (request, result set). It enables much more |
178 well defined context (request, result set). It enables much more |
177 dynamic views. |
179 dynamic views. |
178 |
180 |
179 What is the difference between `AppRsetObject` and `AppObject` ? |
181 What is the difference between `AppRsetObject` and `AppObject` ? |
180 ---------------------------------------------------------------- |
182 ---------------------------------------------------------------- |
181 |
183 |
182 `AppRsetObject` instances are selected on a request and a result |
184 `AppRsetObject` instances are selected on a request and a result |
183 set. `AppObject` instances are directly selected by id. |
185 set. `AppObject` instances are directly selected by id. |
184 |
186 |
185 How to update a database after a schema modification ? |
187 How to update a database after a schema modification ? |
186 ------------------------------------------------------ |
188 ------------------------------------------------------ |
187 |
189 |
188 It depends on what has been modified in the schema. |
190 It depends on what has been modified in the schema. |
189 |
191 |
190 * Update the permissions and properties of an entity or a relation: |
192 * Update the permissions and properties of an entity or a relation: |
191 ``sync_schema_props_perms('MyEntityOrRelation')``. |
193 ``sync_schema_props_perms('MyEntityOrRelation')``. |
192 |
194 |
193 * Add an attribute: ``add_attribute('MyEntityType', 'myattr')``. |
195 * Add an attribute: ``add_attribute('MyEntityType', 'myattr')``. |
194 |
196 |
195 * Add a relation: ``add_relation_definition('SubjRelation', 'MyRelation', 'ObjRelation')``. |
197 * Add a relation: ``add_relation_definition('SubjRelation', 'MyRelation', 'ObjRelation')``. |
196 |
198 |
197 |
199 |
198 How to create an anonymous user ? |
200 How to create an anonymous user ? |
199 --------------------------------- |
201 --------------------------------- |
200 |
202 |
201 This allows to bypass authentication for your site. In the |
203 This allows to bypass authentication for your site. In the |
202 ``all-in-one.conf`` file of your instance, define the anonymous user |
204 ``all-in-one.conf`` file of your instance, define the anonymous user |
203 as follows :: |
205 as follows :: |
204 |
206 |
205 # login of the CubicWeb user account to use for anonymous user (if you want to |
207 # login of the CubicWeb user account to use for anonymous user (if you want to |
206 # allow anonymous) |
208 # allow anonymous) |
207 anonymous-user=anon |
209 anonymous-user=anon |
208 |
210 |
209 # password of the CubicWeb user account matching login |
211 # password of the CubicWeb user account matching login |
210 anonymous-password=anon |
212 anonymous-password=anon |
211 |
213 |
212 You also must ensure that this `anon` user is a registered user of |
214 You also must ensure that this `anon` user is a registered user of |
213 the DB backend. If not, you can create through the administation |
215 the DB backend. If not, you can create through the administation |
214 interface of your instance by adding a user with the role `guests`. |
216 interface of your instance by adding a user with the role `guests`. |
215 This could be the admin account (for development |
217 This could be the admin account (for development |
216 purposes, of course). |
218 purposes, of course). |
217 |
219 |
218 .. note:: |
220 .. note:: |
219 While creating a new instance, you can decide to allow access |
221 While creating a new instance, you can decide to allow access |
220 to anonymous user, which will automatically execute what is |
222 to anonymous user, which will automatically execute what is |
221 decribed above. |
223 decribed above. |
222 |
224 |
223 |
225 |
224 How to change the instance logo ? |
226 How to change the instance logo ? |
225 ------------------------------------ |
227 ------------------------------------ |
226 |
228 |
227 There are two ways of changing the logo. |
229 There are two ways of changing the logo. |
228 |
230 |
229 1. The easiest way to use a different logo is to replace the existing |
231 1. The easiest way to use a different logo is to replace the existing |
230 ``logo.png`` in ``myapp/data`` by your prefered icon and refresh. |
232 ``logo.png`` in ``myapp/data`` by your prefered icon and refresh. |
231 By default all instance will look for a ``logo.png`` to be |
233 By default all instance will look for a ``logo.png`` to be |
232 rendered in the logo section. |
234 rendered in the logo section. |
233 |
235 |
234 .. image:: ../images/lax-book.06-main-template-logo.en.png |
236 .. image:: ../images/lax-book.06-main-template-logo.en.png |
235 |
237 |
236 2. In your cube directory, you can specify which file to use for the logo. |
238 2. In your cube directory, you can specify which file to use for the logo. |
237 This is configurable in ``mycube/data/external_resources``: :: |
239 This is configurable in ``mycube/data/external_resources``: :: |
238 |
240 |
239 LOGO = DATADIR/path/to/mylogo.gif |
241 LOGO = DATADIR/path/to/mylogo.gif |
240 |
242 |
241 where DATADIR is ``mycube/data``. |
243 where DATADIR is ``mycube/data``. |
242 |
244 |
243 |
245 |
244 How to configure a LDAP source ? |
246 How to configure a LDAP source ? |
245 -------------------------------- |
247 -------------------------------- |
246 |
248 |
247 Your instance's sources are defined in ``/etc/cubicweb.d/myapp/sources``. |
249 Your instance's sources are defined in ``/etc/cubicweb.d/myapp/sources``. |
248 Configuring an LDAP source is about declaring that source in your |
250 Configuring an LDAP source is about declaring that source in your |
249 instance configuration file such as: :: |
251 instance configuration file such as: :: |
250 |
252 |
251 [ldapuser] |
253 [ldapuser] |
252 adapter=ldapuser |
254 adapter=ldapuser |
253 # ldap host |
255 # ldap host |
254 host=myhost |
256 host=myhost |
255 # base DN to lookup for usres |
257 # base DN to lookup for usres |
256 user-base-dn=ou=People,dc=mydomain,dc=fr |
258 user-base-dn=ou=People,dc=mydomain,dc=fr |
257 # user search scope |
259 # user search scope |
258 user-scope=ONELEVEL |
260 user-scope=ONELEVEL |
259 # classes of user |
261 # classes of user |
260 user-classes=top,posixAccount |
262 user-classes=top,posixAccount |
261 # attribute used as login on authentication |
263 # attribute used as login on authentication |
262 user-login-attr=uid |
264 user-login-attr=uid |
263 # name of a group in which ldap users will be by default |
265 # name of a group in which ldap users will be by default |
264 user-default-group=users |
266 user-default-group=users |
265 # map from ldap user attributes to cubicweb attributes |
267 # map from ldap user attributes to cubicweb attributes |
266 user-attrs-map=gecos:email,uid:login |
268 user-attrs-map=gecos:email,uid:login |
267 |
269 |
268 Any change applied to configuration file requires to restart your |
270 Any change applied to configuration file requires to restart your |
269 instance. |
271 instance. |
270 |
272 |
271 I get NoSelectableObject exceptions, how do I debug selectors ? |
273 I get NoSelectableObject exceptions, how do I debug selectors ? |
272 --------------------------------------------------------------- |
274 --------------------------------------------------------------- |
273 |
275 |
274 You just need to put the appropriate context manager around view/component |
276 You just need to put the appropriate context manager around view/component |
275 selection (one standard place in in vreg.py) : :: |
277 selection (one standard place in in vreg.py): |
|
278 |
|
279 .. sourcecode:: python |
276 |
280 |
277 def possible_objects(self, registry, *args, **kwargs): |
281 def possible_objects(self, registry, *args, **kwargs): |
278 """return an iterator on possible objects in a registry for this result set |
282 """return an iterator on possible objects in a registry for this result set |
279 |
283 |
280 actions returned are classes, not instances |
284 actions returned are classes, not instances |
285 try: |
289 try: |
286 yield self.select(vobjects, *args, **kwargs) |
290 yield self.select(vobjects, *args, **kwargs) |
287 except NoSelectableObject: |
291 except NoSelectableObject: |
288 continue |
292 continue |
289 |
293 |
290 Don't forget the 'from __future__ improt with_statement' at the |
294 Don't forget the 'from __future__ import with_statement' at the module |
291 module top-level. |
295 top-level. |
292 |
296 |
293 This will yield additional WARNINGs, like this: |
297 This will yield additional WARNINGs, like this:: |
294 :: |
|
295 |
298 |
296 2009-01-09 16:43:52 - (cubicweb.selectors) WARNING: selector one_line_rset returned 0 for <class 'cubicweb.web.views.basecomponents.WFHistoryVComponent'> |
299 2009-01-09 16:43:52 - (cubicweb.selectors) WARNING: selector one_line_rset returned 0 for <class 'cubicweb.web.views.basecomponents.WFHistoryVComponent'> |
297 |
300 |
298 How to format an entity date attribute ? |
301 How to format an entity date attribute ? |
299 ---------------------------------------- |
302 ---------------------------------------- |
300 |
303 |
301 If your schema has an attribute of type Date or Datetime, you might |
304 If your schema has an attribute of type Date or Datetime, you might |
302 want to format it. First, you should define your preferred format using |
305 want to format it. First, you should define your preferred format using |
303 the site configuration panel ``http://appurl/view?vid=systempropertiesform`` |
306 the site configuration panel ``http://appurl/view?vid=systempropertiesform`` |
304 and then set ``ui.date`` and/or ``ui.datetime``. |
307 and then set ``ui.date`` and/or ``ui.datetime``. |
305 Then in the view code, use:: |
308 Then in the view code, use: |
|
309 |
|
310 .. sourcecode:: python |
306 |
311 |
307 self.format_date(entity.date_attribute) |
312 self.format_date(entity.date_attribute) |
308 |
313 |
309 Can PostgreSQL and CubicWeb authentication work with kerberos ? |
314 Can PostgreSQL and CubicWeb authentication work with kerberos ? |
310 ---------------------------------------------------------------- |
315 ---------------------------------------------------------------- |
311 |
316 |
312 If you have PostgreSQL set up to accept kerberos authentication, you can set |
317 If you have PostgreSQL set up to accept kerberos authentication, you can set |
313 the db-host, db-name and db-user parameters in the `sources` configuration |
318 the db-host, db-name and db-user parameters in the `sources` configuration |
314 file while leaving the password blank. It should be enough for your |
319 file while leaving the password blank. It should be enough for your |
315 instance to connect to postgresql with a kerberos ticket. |
320 instance to connect to postgresql with a kerberos ticket. |
316 |
321 |
317 |
322 |
318 How to load data from a script ? |
323 How to load data from a script ? |
319 -------------------------------- |
324 -------------------------------- |
320 |
325 |
321 The following script aims at loading data within a script assuming pyro-nsd is |
326 The following script aims at loading data within a script assuming pyro-nsd is |
322 running and your instance is configured with ``pyro-server=yes``, otherwise |
327 running and your instance is configured with ``pyro-server=yes``, otherwise |
323 you would not be able to use dbapi. :: |
328 you would not be able to use dbapi. |
|
329 |
|
330 .. sourcecode:: python |
324 |
331 |
325 from cubicweb import dbapi |
332 from cubicweb import dbapi |
326 |
333 |
327 cnx = dbapi.connection(database='instance-id', user='admin', password='admin') |
334 cnx = dbapi.connection(database='instance-id', user='admin', password='admin') |
328 cur = cnx.cursor() |
335 cur = cnx.cursor() |