Main page¶
He takes all the resources of the settings to return them to the template
home.jinja2
. It implemented in pyramid_sacrud.views.sa_home()
.

Pyramid CRUD interface. Provides an administration web interface for Pyramid.
Unlike classic CRUD, pyramid_sacrud
allows overrides and flexibility to
customize your interface, similar to django.contrib.admin
but uses a
different backend to provide resources. New Architecture built on the
resources and mechanism traversal, allows to use it in various cases.
The list of standard backends:
Look how easy it is to use with Pyramid and SQLAlchemy:
from .models import (Model1, Model2, Model3,)
# add SQLAlchemy backend
config.include('ps_alchemy')
# add sacrud and project models
config.include('pyramid_sacrud')
settings = config.registry.settings
settings['pyramid_sacrud.models'] = (('Group1', [Model1, Model2]),
('Group2', [Model3]))
go to http://localhost:6543/sacrud/
Example can be found here https://github.com/sacrud/ps_alchemy/tree/master/example
pip install git+http://github.com/sacrud/pyramid_sacrud.git
pip install pyramid_sacrud
git clone git+http://github.com/sacrud/pyramid_sacrud.git
cd pyramid_sacrud
pip install .
git clone git+http://github.com/sacrud/pyramid_sacrud.git
cd pyramid_sacrud
pip install -e .
1 2 3 4 5 6 7 8 9 10 11 12 | from .models import (Model1, Model2, Model3,)
# add SQLAlchemy backend
config.include('ps_alchemy')
# add pyramid_sacrud and project models
config.include('pyramid_sacrud')
settings = config.registry.settings
settings['pyramid_sacrud.models'] = (
('Group1', [Model1, Model2]),
('Group2', [Model3])
)
|
check it there http://localhost:6543/sacrud/
config.include('pyramid_sacrud', route_prefix='admin')
now it there http://localhost:6543/admin/
pyramid_sacrud
use Jinja2 template renderer.
Just create template file in your project templates/sacrud directory:
yourapp/
└── templates
└── sacrud
└── home.jinja2 <-- custom template for pyramid_sacrud home page
You can find a list of all the templates here https://github.com/sacrud/pyramid_sacrud/tree/master/pyramid_sacrud/templates/sacrud
See also
For more information see Internationalization and Localization
To translate widgets on main page, you can use standard translate method for Pyramid.
from pyramid.i18n import TranslationStringFactory
_ = TranslationStringFactory('myapplication')
settings['pyramid_sacrud.models'] = (
(_('Permissions'), (
UserPermission,
UserGroup,
Group,
GroupPermission,
Resource,
UserResourcePermission,
GroupResourcePermission,
ExternalIdentity,
)
),
(_('Users'), (User, Staff))
)
If you use RootFactory for authorization, set PYRAMID_SACRUD_HOME
permission for you accessed to pyramid_sacrud.
from pyramid_sacrud import PYRAMID_SACRUD_HOME
from pyramid.config import Configurator
from pyramid.session import SignedCookieSessionFactory
if __name__ == '__main__':
my_session_factory = SignedCookieSessionFactory('itsaseekreet')
config = Configurator(session_factory=my_session_factory)
config.include('pyramid_sacrud', route_prefix='admin')
app = config.make_wsgi_app()
from wsgiref.simple_server import make_server
server = make_server('0.0.0.0', 6543, app)
server.serve_forever()
Simple admin web interface without resources.
$ cd examples/simple/
$ python main.py
and goto http://localhost:6543/admin/
Simple admin web interface with custom resource ‘Bear’.
It uses custom template bear.jinja2
to display resource Bear
.
$ cd examples/custom_resource/
$ python main.py
and goto http://localhost:6543/admin/
from zope.interface import implementer
from pyramid.view import view_config
from pyramid.config import Configurator
from pyramid_sacrud import PYRAMID_SACRUD_VIEW
from pyramid_sacrud.interfaces import ISacrudResource
@implementer(ISacrudResource)
class Bear(object):
breadcrumb = True
def __init__(self, name, url=None):
self.name = name
self.url = url
@property
def verbose_name(self):
return self.name
@property
def __name__(self):
return self.verbose_name
@view_config(
context=Bear,
renderer='bear.jinja2',
route_name=PYRAMID_SACRUD_VIEW
)
def admin_bear_view(context, request):
return {}
if __name__ == '__main__':
config = Configurator()
# Setting up pyramid_sacrud
config.include('pyramid_sacrud', route_prefix='admin')
settings = config.get_settings()
settings['pyramid_sacrud.models'] = (
('Bears', [
Bear(
'Brown',
'http://i.imgur.com/D5SBanK.jpg'
),
Bear(
'Panda',
'http://i.imgur.com/uiJWAf3.jpg'
),
Bear(
'Polar',
'http://i.imgur.com/j5SDeeH.jpg'
)
]),
)
# Make app
config.scan('.')
app = config.make_wsgi_app()
# Start app
from wsgiref.simple_server import make_server
server = make_server('0.0.0.0', 6543, app)
server.serve_forever()
{% extends "sacrud/redefineme.jinja2" %}
{% block body %}
<h1>{{ context.verbose_name }}</h1>
<img src="{{ context.url }}" width=600px />
{% endblock %}
Simple admin web interface with CRUD operation for docker images. You can delete and view it. In example uses default crud templates from ps_crud module.
$ cd examples/docker_crud/
$ pip install -e .
$ pserve development.ini --reload
and goto http://localhost:6543/admin/
pyramid_sacrud
copes with the resource technology, especially those who
adhere to the principle of Pyramid traversal
.
In this example, we create resources, associate them with the own views, but
inherit the templates from pyramid_sacrud
and ps_crud.
Also entry point for all resources from pyramid_sacrud
settings is
GroupResource
.
When you pass the Docker
in pyramid_sacrud
settings, it automatically
derives from GroupResource
.
Docker
is a base resource and it not displayed in the Web interface,
therefore it doesn’t require binding to the view.
class Docker(object):
breadcrumb = True
def __init__(self):
self.cli = docker.Client(base_url='unix://var/run/docker.sock')
@property
def verbose_name(self):
return self.__class__.__name__ + "'s"
@property
def __name__(self):
return self.verbose_name
Image
represent a list of all docker images in Web interface.
class Image(Docker):
def _get_id(self, row):
return row['Id']
@property
def _columns(self):
class Column:
def __init__(self, name, value):
self.name = name
self.value = value
def value(self, row):
return self.value(row)
return (
Column("id", lambda x: x["Id"][:10]),
Column("created",
lambda x: time.strftime("%D %H:%M",
time.localtime(
int(x["Created"])
))),
Column("tag", lambda x: x["RepoTags"][0])
)
def __getitem__(self, name):
if name == 'mass_action':
return self.ps_crud["crud"]["mass_action"]
elif name == 'update':
return self.ps_crud["crud"]["update"]
@property
def ps_crud(self):
mass_action = MassAction()
mass_action.__parent__ = self
update = UpdateFactory()
update.__parent__ = self
return {
"get_id": self._get_id,
"columns": self._columns,
"crud": {
"mass_action": mass_action,
"update": update,
}
}
@property
def all(self):
return self.cli.images()
It uses view:
def admin_docker_list_view(context, request):
"""Show list of docker images."""
return {
'paginator': Page(
context.all,
url_maker=lambda p: request.path_url + "?page=%s" % p,
page=int(request.params.get('page', 1)),
items_per_page=6
)
}
With template ps_crud/list.jinja2
from extension module ps_crud
.
@view_config(
context=Image,
renderer='ps_crud/list.jinja2',
route_name=PYRAMID_SACRUD_VIEW
)
def admin_docker_list_view(context, request):
"""Show list of docker images."""
UpdateFactory
designed to reflect a particular image.
class UpdateFactory(object):
__name__ = "update"
def __getitem__(self, name):
return self.Update(name, self)
def __call__(self, row):
return self[row["Id"]]
class Update(Docker):
__name__ = None
def get_image(self, img_id):
for img in self.cli.images():
if img['Id'] == img_id:
return img
def __init__(self, name, parent):
Docker.__init__(self)
self.__name__ = name
self.__parent__ = parent
self.img = self.get_image(name)
self.ps_crud = parent.__parent__.ps_crud
def admin_docker_update_view(context, request):
from pprint import pformat
return {'data': '<pre>' + pformat(context.img) + '</pre>'}
{% extends "sacrud/base.jinja2" %}
{% block menu_logo %}
<img src="/static/docker.png" width="300px" />
{% endblock %}
{% extends "sacrud/redefineme.jinja2" %}
{% block title %} - {{ _(context.verbose_name) }}{% endblock %}
{% block body %}
<div id="grid_view"></div>
<h4>{{ _(context.verbose_name) }}</h4>
<div class="bordered highlight hoverable z-depth-1">
{{ data|safe }}
</div>
{% endblock %}
Old Architecture is good, but it does not allow use tree structure of
resources and has hard depency from SQLAlchemy
, sacrud
,
sacrud_deform
etc... This is not flexible solution. A new generation of
pyramid_sacrud
>= 0.3.0 represent just interface for any backends, like:
pyramid_sacrud
and provide to you CRUD operations.pyramid_sacrud
and allow to kill itziggform_* - it’s abstract modules, this is what needs to be done. I like the idea of ziggurat_form so I use such names.
He takes all the resources of the settings to return them to the template
home.jinja2
. It implemented in pyramid_sacrud.views.sa_home()
.
He takes all rows of resource, paginate it and return to template list.jinja2
.
It implemented in pyramid_sacrud.views.CRUD.List
. For select action
used sacrud
and sacrud.action.CRUD.read()
.
He delete selected row and redirect to list of rows. It implemented in
pyramid_sacrud.views.CRUD.Delete
. For delete action used sacrud
and sacrud.action.CRUD.delete()
.
If you send GET request it return HTML form for your module. To generate form
it used sacrud_deform
. sacrud_deform generate form with schema from
ColanderAlchemy
and widgets from deform
. The main task of
sacrud_deform
is choose the right widgets from deform
and make
select widget for relationships. It implemented in
pyramid_sacrud.views.CRUD.Add
and used template create.jinja2
.
If you send POST request it validate form and do create/update action from
sacrud
respectively sacrud.action.CRUD.create()
and
sacrud.action.CRUD.update()
. It implemented in
pyramid_sacrud.views.CRUD.Add
.
Same as contributor’s section of the documentation of Pyramid project.
For working with CSS and JavaScript you need install Node.js, npm and WebPack.
Note
If you don’t have Node.js and NPM installed, get it first.
Installing Node.js dependencies:
npm install
СSS files are located in pyramid_sacrud/static/css/. css pack in __main.css file in pyramid_sacrud/static/css/.
Js pack in __main.js in pyramid_sacrud/static/js/assets/.
For update each dependency in package.json, just use npm-check-updates.
$ npm install -g npm-check-updates
$ npm-check-updates -u
$ npm install
gettext
(http://www.gnu.org/software/gettext/).apt-get install gettext
pyramid_sacrud
has certain labels in templates like “Home”, “Create”,
“Delete”, etc. If these labels appear in English on your admin panel although
you specified another language, then this page is for you.
pyramid_sacrud
needs your help for translation of these labels.
Translation process involves the following steps:
Execute extract_messages
each time a translatable message text is changed or
added:
python setup.py extract_messages
or for linux:
make extract_messages
This will create or update pyramid_sacrud/locale/pyramid_sacrud.pot
file,
the central messages catalog used by the different translations.
Execute init_catalog
once for each new language, e.g.:
python setup.py init_catalog -l de -i pyramid_sacrud/locale/pyramid_sacrud.pot -o pyramid_sacrud/locale/de/LC_MESSAGES/pyramid_sacrud.po
This will create a file
pyramid_sacrud/locale/de/LC_MESSAGES/pyramid_sacrud.po
in which
translations needs to be placed.
Execute update_catalog
for each existing language, e.g.:
python setup.py update_catalog
or for linux:
make update_catalog
This will update file
pyramid_sacrud/locale/de/LC_MESSAGES/pyramid_sacrud.po
where translations
of new text needs to be placed.
Execute compile_catalog
for each existing language, e.g.:
python setup.py compile_catalog
or for linux:
make compile_catalog
English locale by default:
Russian locale:
German locale:
See also
For more information about Internationalization and Localization read official pyramid docs http://docs.pylonsproject.org/projects/pyramid/en/latest/narr/i18n.html
Also see basic settings in setup.cfg file (hint steal from here).
For translate use _ps function:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | #! /usr/bin/env python
# -*- coding: utf-8 -*-
# vim:fenc=utf-8
#
# Copyright © 2014 uralbash <root@uralbash.ru>
#
# Distributed under terms of the MIT license.
"""
Internationalization and Localization
"""
from pyramid.i18n import TranslationStringFactory
_ps = TranslationStringFactory('pyramid_sacrud')
def includeme(config):
config.add_translation_dirs('pyramid_sacrud:locale/')
config.scan('.views')
|
Example with Jinja2 template:
<div class="dashboard-title">{{ _ps('Dashboard') }}</div>
{{ _ps(_(crumb.name)) }}
To report bugs, use the issue tracker.
We welcome any contribution: suggestions, ideas, commits with new futures, bug fixes, refactoring, docs, tests, translations etc
If you have question, contact me sacrud@uralbash.ru or IRC channel #sacrud
The project is licensed under the MIT license.