or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

extension-setup.mdform-rendering.mdindex.mdnavigation.mdpagination.mdpython-utilities.mdtable-rendering.mdutilities.md

table-rendering.mddocs/

0

# Table Rendering

1

2

Data table rendering with Bootstrap styling, supporting CRUD actions, responsive design, pagination integration, and flexible column formatting options for displaying data collections.

3

4

## Capabilities

5

6

### Complete Table Rendering

7

8

Render data collections as Bootstrap-styled tables with optional CRUD actions and extensive customization.

9

10

```python { .api }

11

def render_table(data, titles=None, primary_key='id', primary_key_title='#',

12

caption=None, table_classes=None, header_classes=None,

13

body_classes=None, responsive=False, responsive_class='table-responsive',

14

safe_columns=None, urlize_columns=None, model=None,

15

show_actions=False, actions_title='Actions', custom_actions=None,

16

view_url=None, edit_url=None, delete_url=None, new_url=None,

17

action_pk_placeholder=':id'):

18

"""

19

Render a data collection as a Bootstrap table.

20

21

Args:

22

data (list): List of objects/dicts to display in table

23

titles (list): List of (field_name, display_title) tuples for columns

24

primary_key (str): Primary key field name (default: 'id')

25

primary_key_title (str): Display title for primary key column (default: '#')

26

caption (str): Table caption text

27

table_classes (str): CSS classes for table element

28

header_classes (str): CSS classes for table header

29

body_classes (str): CSS classes for table body

30

responsive (bool): Enable responsive table wrapper

31

responsive_class (str): CSS class for responsive wrapper

32

safe_columns (list): Column names to render as safe HTML

33

urlize_columns (list): Column names to convert URLs to links

34

model: SQLAlchemy model class for automatic title detection

35

show_actions (bool): Display CRUD action buttons

36

actions_title (str): Title for actions column

37

custom_actions (list): Custom action button definitions

38

view_url (str): URL pattern for view action

39

edit_url (str): URL pattern for edit action

40

delete_url (str): URL pattern for delete action

41

new_url (str): URL for new record creation

42

action_pk_placeholder (str): Placeholder for primary key in URLs

43

44

Returns:

45

Rendered HTML table with Bootstrap styling

46

47

Data Sources:

48

- List of dictionaries

49

- List of SQLAlchemy model instances

50

- List of custom objects with attributes

51

52

URL Patterns:

53

- Use :id placeholder for primary key substitution

54

- Example: '/users/:id/edit' becomes '/users/123/edit'

55

"""

56

```

57

58

### Table Title Generation

59

60

Automatically generate table column titles from SQLAlchemy models.

61

62

```python { .api }

63

def get_table_titles(data, primary_key, primary_key_title):

64

"""

65

Detect and build table titles from SQLAlchemy ORM objects.

66

67

Args:

68

data (list): List of SQLAlchemy model instances

69

primary_key (str): Primary key field name

70

primary_key_title (str): Display title for primary key

71

72

Returns:

73

list: List of (field_name, display_title) tuples

74

75

Behavior:

76

- Extracts column names from SQLAlchemy model metadata

77

- Converts snake_case to Title Case (user_name -> User Name)

78

- Excludes fields starting with underscore

79

- Sets primary key title as specified

80

81

Example:

82

For User model with columns: id, first_name, last_name, email

83

Returns: [('id', '#'), ('first_name', 'First Name'),

84

('last_name', 'Last Name'), ('email', 'Email')]

85

"""

86

```

87

88

### Internal URL Building

89

90

Internal helper for constructing action URLs with dynamic parameters.

91

92

```python { .api }

93

def build_url(record, endpoint, url_tuples, model, pk_field):

94

"""

95

Internal helper to build URLs for table actions.

96

97

Args:

98

record: Data record (dict or object)

99

endpoint (str): Flask endpoint or URL pattern

100

url_tuples (list): URL parameter tuples

101

model: SQLAlchemy model class

102

pk_field (str): Primary key field name

103

104

Returns:

105

str: Constructed URL with substituted parameters

106

107

Note: This is an internal helper used by render_table

108

"""

109

```

110

111

## Table Features

112

113

### Data Source Support

114

115

Bootstrap-Flask tables support multiple data source types:

116

117

#### Dictionary Lists

118

```python

119

data = [

120

{'id': 1, 'name': 'John Doe', 'email': 'john@example.com'},

121

{'id': 2, 'name': 'Jane Smith', 'email': 'jane@example.com'},

122

]

123

```

124

125

#### SQLAlchemy Model Instances

126

```python

127

users = User.query.all() # List of SQLAlchemy model instances

128

```

129

130

#### Custom Objects

131

```python

132

class Person:

133

def __init__(self, id, name, email):

134

self.id = id

135

self.name = name

136

self.email = email

137

138

data = [Person(1, 'John', 'john@example.com')]

139

```

140

141

### Column Configuration

142

143

#### Manual Title Definition

144

```python

145

titles = [

146

('id', '#'),

147

('first_name', 'First Name'),

148

('last_name', 'Last Name'),

149

('email', 'Email Address'),

150

('created_at', 'Date Created')

151

]

152

```

153

154

#### Automatic Title Generation

155

```python

156

# For SQLAlchemy models - automatically generates titles

157

titles = get_table_titles(users, 'id', '#')

158

```

159

160

### CRUD Actions

161

162

Bootstrap-Flask provides built-in CRUD action buttons:

163

164

#### Standard Actions

165

- **View**: Display record details

166

- **Edit**: Modify record

167

- **Delete**: Remove record

168

- **New**: Create new record

169

170

#### Action URL Patterns

171

```python

172

# URL patterns with :id placeholder

173

view_url = '/users/:id'

174

edit_url = '/users/:id/edit'

175

delete_url = '/users/:id/delete'

176

new_url = '/users/new'

177

```

178

179

#### Custom Actions

180

```python

181

custom_actions = [

182

{

183

'title': 'Activate',

184

'url': '/users/:id/activate',

185

'classes': 'btn-success btn-sm'

186

},

187

{

188

'title': 'Archive',

189

'url': '/users/:id/archive',

190

'classes': 'btn-warning btn-sm'

191

}

192

]

193

```

194

195

### Column Formatting

196

197

#### Safe HTML Columns

198

Render column content as safe HTML without escaping:

199

200

```python

201

safe_columns = ['description', 'notes'] # Won't escape HTML tags

202

```

203

204

#### URL Columns

205

Automatically convert URLs to clickable links:

206

207

```python

208

urlize_columns = ['website', 'blog_url'] # Convert to <a> tags

209

```

210

211

### Responsive Design

212

213

Tables can be made responsive to handle overflow on small screens:

214

215

```python

216

# Enable responsive wrapper

217

responsive = True

218

responsive_class = 'table-responsive-md' # Responsive on medium screens and below

219

```

220

221

## Usage Examples

222

223

### Basic Table

224

225

```python

226

# View function

227

@app.route('/users')

228

def users():

229

users = [

230

{'id': 1, 'name': 'John Doe', 'email': 'john@example.com'},

231

{'id': 2, 'name': 'Jane Smith', 'email': 'jane@example.com'},

232

]

233

return render_template('users.html', users=users)

234

```

235

236

```html

237

<!-- Template -->

238

{% from 'base/table.html' import render_table %}

239

240

<div class="container">

241

<h2>Users</h2>

242

{{ render_table(users) }}

243

</div>

244

```

245

246

### Table with Custom Styling

247

248

```html

249

{{ render_table(users,

250

table_classes="table table-striped table-hover table-bordered",

251

header_classes="table-dark",

252

caption="List of registered users"

253

) }}

254

```

255

256

### Table with CRUD Actions

257

258

```html

259

{{ render_table(users,

260

show_actions=True,

261

view_url="/users/:id",

262

edit_url="/users/:id/edit",

263

delete_url="/users/:id/delete",

264

new_url="/users/new",

265

actions_title="Operations"

266

) }}

267

```

268

269

### SQLAlchemy Model Table

270

271

```python

272

# Model

273

class User(db.Model):

274

id = db.Column(db.Integer, primary_key=True)

275

first_name = db.Column(db.String(50))

276

last_name = db.Column(db.String(50))

277

email = db.Column(db.String(120))

278

created_at = db.Column(db.DateTime)

279

280

# View

281

@app.route('/users')

282

def users():

283

users = User.query.all()

284

titles = get_table_titles(users, 'id', 'User ID')

285

return render_template('users.html', users=users, titles=titles)

286

```

287

288

```html

289

{{ render_table(users, titles=titles, model=User, show_actions=True) }}

290

```

291

292

### Responsive Table with Custom Columns

293

294

```html

295

{{ render_table(products,

296

titles=[

297

('id', 'ID'),

298

('name', 'Product Name'),

299

('description', 'Description'),

300

('price', 'Price'),

301

('website', 'Website')

302

],

303

responsive=True,

304

responsive_class="table-responsive-lg",

305

safe_columns=['description'],

306

urlize_columns=['website'],

307

table_classes="table table-sm"

308

) }}

309

```

310

311

### Table with Custom Actions

312

313

```html

314

{{ render_table(orders,

315

show_actions=True,

316

custom_actions=[

317

{

318

'title': 'Ship',

319

'url': '/orders/:id/ship',

320

'classes': 'btn-success btn-sm'

321

},

322

{

323

'title': 'Cancel',

324

'url': '/orders/:id/cancel',

325

'classes': 'btn-danger btn-sm'

326

},

327

{

328

'title': 'Invoice',

329

'url': '/orders/:id/invoice',

330

'classes': 'btn-info btn-sm'

331

}

332

]

333

) }}

334

```

335

336

### Table with Pagination Integration

337

338

```python

339

# View with pagination

340

@app.route('/users')

341

def users():

342

page = request.args.get('page', 1, type=int)

343

users = User.query.paginate(

344

page=page, per_page=10, error_out=False

345

)

346

return render_template('users.html', users=users)

347

```

348

349

```html

350

{% from 'base/table.html' import render_table %}

351

{% from 'base/pagination.html' import render_pagination %}

352

353

{{ render_table(users.items, show_actions=True) }}

354

{{ render_pagination(users) }}

355

```

356

357

### Advanced Configuration

358

359

```html

360

{{ render_table(data,

361

titles=custom_titles,

362

primary_key='user_id',

363

primary_key_title='User ID',

364

table_classes="table table-striped table-hover",

365

header_classes="table-primary",

366

body_classes="small",

367

responsive=True,

368

responsive_class="table-responsive-md",

369

safe_columns=['bio', 'notes'],

370

urlize_columns=['website', 'linkedin'],

371

show_actions=True,

372

actions_title="Manage",

373

view_url="/users/:id/profile",

374

edit_url="/users/:id/settings",

375

delete_url="/admin/users/:id/delete",

376

new_url="/users/register",

377

action_pk_placeholder=':id'

378

) }}

379

```

380

381

### Empty Table Handling

382

383

```html

384

{% if data %}

385

{{ render_table(data) }}

386

{% else %}

387

<div class="alert alert-info">

388

<h4>No Records Found</h4>

389

<p>There are currently no records to display.</p>

390

<a href="{{ url_for('new_record') }}" class="btn btn-primary">

391

Add New Record

392

</a>

393

</div>

394

{% endif %}

395

```

396

397

## Configuration Variables

398

399

Table rendering respects several Flask configuration variables:

400

401

```python

402

# Table action button titles (configurable)

403

app.config['BOOTSTRAP_TABLE_VIEW_TITLE'] = 'View'

404

app.config['BOOTSTRAP_TABLE_EDIT_TITLE'] = 'Edit'

405

app.config['BOOTSTRAP_TABLE_DELETE_TITLE'] = 'Delete'

406

app.config['BOOTSTRAP_TABLE_NEW_TITLE'] = 'New'

407

```

408

409

These configuration values are used as default titles for CRUD action buttons and can be overridden at the template level.