This file is indexed.

/usr/share/doc/python-tgext.admin/index.html is in python-tgext.admin 0.2.6-3.

This file is owned by root:root, with mode 0o644.

The actual contents of the file can be viewed below.

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
<?xml version="1.0" encoding="utf-8" ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta name="generator" content="Docutils 0.11: http://docutils.sourceforge.net/" />
<title>TurboGears Administration System</title>
<style type="text/css">

/*
:Author: David Goodger (goodger@python.org)
:Id: $Id: html4css1.css 7614 2013-02-21 15:55:51Z milde $
:Copyright: This stylesheet has been placed in the public domain.

Default cascading style sheet for the HTML output of Docutils.

See http://docutils.sf.net/docs/howto/html-stylesheets.html for how to
customize this style sheet.
*/

/* used to remove borders from tables and images */
.borderless, table.borderless td, table.borderless th {
  border: 0 }

table.borderless td, table.borderless th {
  /* Override padding for "table.docutils td" with "! important".
     The right padding separates the table cells. */
  padding: 0 0.5em 0 0 ! important }

.first {
  /* Override more specific margin styles with "! important". */
  margin-top: 0 ! important }

.last, .with-subtitle {
  margin-bottom: 0 ! important }

.hidden {
  display: none }

a.toc-backref {
  text-decoration: none ;
  color: black }

blockquote.epigraph {
  margin: 2em 5em ; }

dl.docutils dd {
  margin-bottom: 0.5em }

object[type="image/svg+xml"], object[type="application/x-shockwave-flash"] {
  overflow: hidden;
}

/* Uncomment (and remove this text!) to get bold-faced definition list terms
dl.docutils dt {
  font-weight: bold }
*/

div.abstract {
  margin: 2em 5em }

div.abstract p.topic-title {
  font-weight: bold ;
  text-align: center }

div.admonition, div.attention, div.caution, div.danger, div.error,
div.hint, div.important, div.note, div.tip, div.warning {
  margin: 2em ;
  border: medium outset ;
  padding: 1em }

div.admonition p.admonition-title, div.hint p.admonition-title,
div.important p.admonition-title, div.note p.admonition-title,
div.tip p.admonition-title {
  font-weight: bold ;
  font-family: sans-serif }

div.attention p.admonition-title, div.caution p.admonition-title,
div.danger p.admonition-title, div.error p.admonition-title,
div.warning p.admonition-title, .code .error {
  color: red ;
  font-weight: bold ;
  font-family: sans-serif }

/* Uncomment (and remove this text!) to get reduced vertical space in
   compound paragraphs.
div.compound .compound-first, div.compound .compound-middle {
  margin-bottom: 0.5em }

div.compound .compound-last, div.compound .compound-middle {
  margin-top: 0.5em }
*/

div.dedication {
  margin: 2em 5em ;
  text-align: center ;
  font-style: italic }

div.dedication p.topic-title {
  font-weight: bold ;
  font-style: normal }

div.figure {
  margin-left: 2em ;
  margin-right: 2em }

div.footer, div.header {
  clear: both;
  font-size: smaller }

div.line-block {
  display: block ;
  margin-top: 1em ;
  margin-bottom: 1em }

div.line-block div.line-block {
  margin-top: 0 ;
  margin-bottom: 0 ;
  margin-left: 1.5em }

div.sidebar {
  margin: 0 0 0.5em 1em ;
  border: medium outset ;
  padding: 1em ;
  background-color: #ffffee ;
  width: 40% ;
  float: right ;
  clear: right }

div.sidebar p.rubric {
  font-family: sans-serif ;
  font-size: medium }

div.system-messages {
  margin: 5em }

div.system-messages h1 {
  color: red }

div.system-message {
  border: medium outset ;
  padding: 1em }

div.system-message p.system-message-title {
  color: red ;
  font-weight: bold }

div.topic {
  margin: 2em }

h1.section-subtitle, h2.section-subtitle, h3.section-subtitle,
h4.section-subtitle, h5.section-subtitle, h6.section-subtitle {
  margin-top: 0.4em }

h1.title {
  text-align: center }

h2.subtitle {
  text-align: center }

hr.docutils {
  width: 75% }

img.align-left, .figure.align-left, object.align-left {
  clear: left ;
  float: left ;
  margin-right: 1em }

img.align-right, .figure.align-right, object.align-right {
  clear: right ;
  float: right ;
  margin-left: 1em }

img.align-center, .figure.align-center, object.align-center {
  display: block;
  margin-left: auto;
  margin-right: auto;
}

.align-left {
  text-align: left }

.align-center {
  clear: both ;
  text-align: center }

.align-right {
  text-align: right }

/* reset inner alignment in figures */
div.align-right {
  text-align: inherit }

/* div.align-center * { */
/*   text-align: left } */

ol.simple, ul.simple {
  margin-bottom: 1em }

ol.arabic {
  list-style: decimal }

ol.loweralpha {
  list-style: lower-alpha }

ol.upperalpha {
  list-style: upper-alpha }

ol.lowerroman {
  list-style: lower-roman }

ol.upperroman {
  list-style: upper-roman }

p.attribution {
  text-align: right ;
  margin-left: 50% }

p.caption {
  font-style: italic }

p.credits {
  font-style: italic ;
  font-size: smaller }

p.label {
  white-space: nowrap }

p.rubric {
  font-weight: bold ;
  font-size: larger ;
  color: maroon ;
  text-align: center }

p.sidebar-title {
  font-family: sans-serif ;
  font-weight: bold ;
  font-size: larger }

p.sidebar-subtitle {
  font-family: sans-serif ;
  font-weight: bold }

p.topic-title {
  font-weight: bold }

pre.address {
  margin-bottom: 0 ;
  margin-top: 0 ;
  font: inherit }

pre.literal-block, pre.doctest-block, pre.math, pre.code {
  margin-left: 2em ;
  margin-right: 2em }

pre.code .ln { color: grey; } /* line numbers */
pre.code, code { background-color: #eeeeee }
pre.code .comment, code .comment { color: #5C6576 }
pre.code .keyword, code .keyword { color: #3B0D06; font-weight: bold }
pre.code .literal.string, code .literal.string { color: #0C5404 }
pre.code .name.builtin, code .name.builtin { color: #352B84 }
pre.code .deleted, code .deleted { background-color: #DEB0A1}
pre.code .inserted, code .inserted { background-color: #A3D289}

span.classifier {
  font-family: sans-serif ;
  font-style: oblique }

span.classifier-delimiter {
  font-family: sans-serif ;
  font-weight: bold }

span.interpreted {
  font-family: sans-serif }

span.option {
  white-space: nowrap }

span.pre {
  white-space: pre }

span.problematic {
  color: red }

span.section-subtitle {
  /* font-size relative to parent (h1..h6 element) */
  font-size: 80% }

table.citation {
  border-left: solid 1px gray;
  margin-left: 1px }

table.docinfo {
  margin: 2em 4em }

table.docutils {
  margin-top: 0.5em ;
  margin-bottom: 0.5em }

table.footnote {
  border-left: solid 1px black;
  margin-left: 1px }

table.docutils td, table.docutils th,
table.docinfo td, table.docinfo th {
  padding-left: 0.5em ;
  padding-right: 0.5em ;
  vertical-align: top }

table.docutils th.field-name, table.docinfo th.docinfo-name {
  font-weight: bold ;
  text-align: left ;
  white-space: nowrap ;
  padding-left: 0 }

/* "booktabs" style (no vertical lines) */
table.docutils.booktabs {
  border: 0px;
  border-top: 2px solid;
  border-bottom: 2px solid;
  border-collapse: collapse;
}
table.docutils.booktabs * {
  border: 0px;
}
table.docutils.booktabs th {
  border-bottom: thin solid;
  text-align: left;
}

h1 tt.docutils, h2 tt.docutils, h3 tt.docutils,
h4 tt.docutils, h5 tt.docutils, h6 tt.docutils {
  font-size: 100% }

ul.auto-toc {
  list-style-type: none }

</style>
</head>
<body>
<div class="document" id="turbogears-administration-system">
<h1 class="title">TurboGears Administration System</h1>

<!-- tgext.admin documentation master file, created by sphinx-quickstart on Mon Jan 19 21:36:58 2009.
You can adapt this file completely to your liking, but it should at least
contain the root `toctree` directive. -->
<div class="section" id="overview">
<h1>Overview</h1>
<p>The TurboGears Admin is a powerful system to create automated CRUD for your application.
It provides a fully configurable interface and ajax capabilities.  The default admin
is configured to work with the paster quickstart template, but can be easily modified to fit
your application's needs.  Forms are automatically validated, and the URL structure
for all requests is based on HTTP verbs, also known as RESTful URLs. Here is a basic overview
of how the components that make up the TurboGears Admin interact with your application.</p>
<img alt="images/class_diagram.png" src="images/class_diagram.png" />
</div>
<div class="section" id="adding-admincontroller-to-your-tg-application">
<h1>Adding AdminController to your TG application</h1>
<p>AdminController is like any other TGController, it can be added directly to any part of your
system simply by making it part of an existing Controller Class.  Here is how you would add it to
the root controller:</p>
<pre class="literal-block">
from tgext.admin import AdminController
from myproject import model
from myproject.model import DBSession

class RootController(BaseController):
    admin = AdminController(model, DBSession)
</pre>
<div class="section" id="using-multiple-databases">
<h2>Using Multiple Databases</h2>
<p>AdminController gets tied to a particular database session and set of models.  For this reason,
you need to create a new AdminController for each database you wish to express.  Therefore, once
you have your database connections setup in your project's model code, you might have a controller
that looks something like this:</p>
<pre class="literal-block">
from tgext.admin import AdminController
from myproject.model import model1
from myproject.model import model2

from myproject.model import DB1Session, DB2Session

class RootController(BaseController):
    db1admin = AdminController(db1model, DB1Session)
    db2admin = AdminController(db2model, DB2Session)
</pre>
</div>
<div class="section" id="limiting-the-models-shown-in-your-admin">
<h2>Limiting the Models Shown in your Admin</h2>
<p>The first element of AdminController can either take a module that contains mapped model classes, or a list of model classes that
are mapped.  For instance, if you wanted to limit the AdminController to just User and Group classes, you would
have code as follows:</p>
<pre class="literal-block">
from tgext.admin import AdminController
from myproject.model import User, Group, DBSession

class RootController(BaseController):
    admin = AdminController([User, Group], DBSession)
</pre>
</div>
<div class="section" id="securing-your-admin">
<h2>Securing your Admin</h2>
<p>By default, AdminController is securred by limiting access only to users in the &quot;managers&quot; group.
You can subclass AdminController and provide whatever predicate you desire.  For example, you could change
the permissions to allow anyone with the 'manage' permission access with the following code:</p>
<pre class="literal-block">
from repoze.what.predicates import has_permission
from tgext.admin import AdminController
from repoze.what.predicates import in_group

class MyAdminController(AdminControler):
    allow_only = has_permission('manage')
</pre>
<p>For more information, please see <a href="#id1"><span class="problematic" id="id2">:mod:`repoze.what`</span></a></p>
<div class="system-message" id="id1">
<p class="system-message-title">System Message: ERROR/3 (<tt class="docutils">index.rst</tt>, line 81); <em><a href="#id2">backlink</a></em></p>
Unknown interpreted text role &quot;mod&quot;.</div>
</div>
<div class="section" id="utilizing-translations-from-repoze-what">
<h2>Utilizing Translations from repoze.what</h2>
<p>If you have an existing database format that you are retrofitting to the TurboGears,
you can utilize you existing translation for identity with some additions for use in
the default AdminController.</p>
<p>Probably if you are here, you have already modified your app_cfg.py file to take into
account the translations from the standard TG names to those of your system.  This might
look something like this:</p>
<pre class="literal-block">
base_config.sa_auth.translations = {&quot;user_id&quot;:&quot;userID&quot;,
                                    &quot;user_name&quot;: &quot;userName&quot;,
                                    &quot;group_id&quot;:&quot;groupID&quot;,
                                    }
</pre>
<p>You may also need to override other fields like permission_id and permission_name that
are not the same in the tg schema.  These are also ok to add to the sa_auth.translation
configuration option in the base_config.  You can now pass these translations into the
AdminController and have it render it's forms as they pertain to your database schema.:</p>
<pre class="literal-block">
from tgext.admin import AdminController
from myproject import model
from myproject.model import DBSession
from tg import config

class RootController(BaseController):
    admin = AdminController(model, DBSession, translations=config.sa_auth.translations)
</pre>
</div>
</div>
<div class="section" id="using-adminconfig">
<h1>Using AdminConfig</h1>
<p>The TurboGears Admin comes configured out-of-the-box for use with the default quickstarted
template model, but your application may have different needs.  TurboGears Admin is designed
to meet those needs head on, allowing you to leave most boiler plate behind, while overriding
the components of your application that are unique to your needs.</p>
<div class="section" id="starting-with-a-blank-slate">
<h2>Starting with a Blank Slate</h2>
<p>The TGAdminConfig which is the default actually does quite a bit of overriding for you, so that
your forms and tables will look nice the first time you use it.  We can set the AdminController
back to what Sprox uses for defaults, selecting form field information directly from the
database metadata.  This is roughly equivilent to the view Catwalk provides, minus the
menu on the side.:</p>
<pre class="literal-block">
from tgext.admin import AdminController, AdminConfig

class MyAdminConfig(AdminConfig):

class RootController(BaseController):
    admin = AdminController(model, DBSession, config_type=AdminConfig)
</pre>
<p>Notice that we send the AdminConfig class un-instantiated.  By creating the Config instance at execution time,
the transaction manager can handle the sessions properly, as well
and the creation of forms can happen dynamically as the Classes in your Model are accessed.  This translates to speed
and robustness.</p>
</div>
<div class="section" id="overriding-the-index-template">
<h2>Overriding the Index Template</h2>
<p>Chances are, if your model is complex, an alphabetical list of Classes on the index page is not going
to suit your needs. Luckily, the default template can be replaced with one of your own making
without too much trouble.
Simply subclass AdminController, providing your own default template.  It is a good idea to provide
the engine name explicitly in your template definition.:</p>
<pre class="literal-block">
from tgext.admin import AdminController, AdminConfig

class MyAdminConfig(AdminConfig):
    default_index_template = &quot;genshi:myproject.myadmintemplate&quot;

class RootController(BaseController):
    admin = AdminController(model, DBSession, config_type=MyAdminConfig)
</pre>
</div>
<div class="section" id="modifying-crud-controller-types">
<h2>Modifying CRUD Controller Types</h2>
<p>In a similar manner that Sprox treats Model Fields, AdminConfig treats a grouping of Models.
Each model has associated with it a CrudRestController.  This is a controller that performs
all of the crud operations using RESTful URLs.  The attributes of AdminController which are
not &quot;index&quot; define the models controller type within the context of AdminController.  AdminController
performs a lookup to it's AdminConfig to see what type of CrudRestController it should use
when a request has come in which matches one of it's models.  The url dispatch is set to
the model name in all lower case lettering.  If no specific controller type is found for a
particular model, then the default controller is used.</p>
</div>
<div class="section" id="overriding-a-form">
<h2>Overriding a Form</h2>
<p>The classic example shows how to override the &quot;new_form&quot; of the User controller to match a common registration form.
complete with password verification:</p>
<div class="system-message">
<p class="system-message-title">System Message: ERROR/3 (<tt class="docutils">index.rst</tt>, line 175)</p>
Unexpected indentation.</div>
<pre class="literal-block">
from tgext.admin.config import AdminConfig, CrudRestControllerConfig
from sprox.formbase import AddFormBase
from formencode import Schema
from formencode.validators import FieldsMatch
from tw.forms import PasswordField, TextField

form_validator =  Schema(chained_validators=(FieldsMatch('password',
                                                         'verify_password',
                                                         messages={'invalidNoMatch':
                                                         'Passwords do not match'}),))
class RegistrationForm(AddRecordForm):
    __model__ = User
    __require_fields__     = ['password', 'user_name', 'email_address']
    __omit_fields__        = ['_password', 'groups', 'created', 'user_id', 'town_id']
    __field_order__        = ['user_name', 'email_address', 'display_name', 'password', 'verify_password']
    __base_validator__     = form_validator
    email_address          = TextField
    display_name           = TextField
    verify_password        = PasswordField('verify_password')


class UserCrudConfig(CrudRestControllerConfig):
    new_form_type = Registration_form

class MyAdminConfig(AdminConfig):
    user = UserCrudConfig

class RootController(BaseController):
    admin = AdminController(model, DBSession, config_type=MyAdminConfig)
</pre>
<p>Again, notice we override the &quot;user&quot; attribute of AdminConfig, which AdminController introspects to determine
how to create a controller for the User object.</p>
</div>
<div class="section" id="overriding-a-table">
<h2>Overriding a Table</h2>
<p>Often times you will want to hide some columsn which are not very useful to the user, such as id keys that point
to relations within the object.  The TGAdmin allows you to override these parts of the system using the Sprox Base
classes. Here is an example of how to create an AdminConfig which limits the User table to display_name and email_address:</p>
<pre class="literal-block">
from tgext.admin.config import AdminConfig, CrudRestControllerConfig
from sprox.tablebase import TableBase
from sprox.fillerbase import TableFiller

class MyAdminConfig(AdminConfig):
    class user(CrudRestControllerConfig):
        class table_type(TableBase):
                __entity__ = User
                __limit_fields__ = ['display_name', 'email_address']
                __url__ = '../user.json' #this just tidies up the URL a bit

        class table_filler_type(TableFiller):
                __entity__ = User
                __limit_fields__ = ['user_id', 'display_name', 'email_address']

class RootController(BaseController):
    admin = AdminController(model, DBSession, config_type=MyAdminConfig)
</pre>
<p>You may have noticed that the table_filler_type's limit_fields include's 'user_id'.  This is because the
CrudRestController needs to have access to the primary keys in the model in order to perform it's dispatch.</p>
</div>
<div class="section" id="um-where-d-my-dojo-go">
<h2>Um, where'd my Dojo go?</h2>
<p>Now the tables aren't being rendered by Dojo, so let's add that back.
Simply replace your Sprox imports with:</p>
<pre class="literal-block">
from sprox.dojo.tablebase import DojoTableBase as TableBase
from sprox.dojo.fillerbase import DojoTableFiller as TableFiller
</pre>
</div>
<div class="section" id="overriding-all-form-types-for-the-crud-controllers">
<h2>Overriding All Form types for the CRUD Controllers</h2>
<p>Perhaps you have a CrudRestControllerConfig of your own design.You can make it the default for all of the
CrudController creation in your config.</p>
<pre class="literal-block">
class MyCrudRestControllerConfig(CrudRestControllerConfig):
    ...

class MyAdminConfig(AdminConfig):
    DefaultControllerConfig = MyCrudRestControllerConfig
</pre>
</div>
<div class="section" id="wait-a-minute-is-this-is-just-an-admin-tool">
<h2>Wait a minute, is this is _just_ an Admin tool?</h2>
<p>You may have keyed in on somthing.  TurboGears Admin can be utilized to support more than just Administrative tasks.
Since it is securred the same way the other TurboGears controllers on, you could use it for any user on your system.
The miriad of ways you can override different parts of the system mean that this tool could be an excellent resource
for rapid prototyping of a webapplication, or even as a provider of placeholder for future components.</p>
</div>
</div>
</div>
</body>
</html>