- Set up your system as described in the
README.md
. - if you plan on contributing to muesli, fork the repository and clone it:
$ git clone [email protected]:<your_username>/muesli.git
- create a branch for your changes
$ git checkout -b <your_very_special_branchname>
- develop the changes you want to do
- try to use the correct styling / formatting for your code (Google Stylguidelines(Summary))
- push your changes
$ git push --set-upstream origin <your_very_special_branchname>
- create a pull request: https://github.com/muesli-hd/muesli/new/pull
Muesli currently uses the the following frameworks and programs:
Program | Used for |
---|---|
pyramid_webframework | Access control, handling of HTTP requests |
alembic |
Versioninig for the database |
SQLAlchemy | Managing the models and make changes to the DB |
chameleon |
Templating language to fill the HTML sites |
marshmallow |
Used to serialize object to JSON and back |
cornice |
framework to represent the API |
pyramid_apispec |
framework used to document the API |
Location | What's it good for? |
---|---|
alembic | Database-handling |
docker | directory with docker related scripts and files |
docker/run-tests.sh | used to run the testsuite |
muesli | contains actual code for muesli |
muesli/tests | contains tests for the muesli code |
muesli/web | contains most muesli code |
muesli/models.py | contains all model-definition used in the database |
muesli/web/static | contains JS and CSS |
muesli/web/templates | contains the templates which define the appearance of the Website |
muesli/web/templates/Fragments/main.pt | Is the main template used for elements to appear on all pages |
muesli/web/__init__.py | Here Requests are prepared and routes defined |
muesli/web/navigation_tree.py | Definition and creation of the navigation tree |
muesli/web/views*.py | Contains the code to fill in the templates |
muesli/web/api/* | Contains the module which serves the API |
At the moment tests are minimal, most pages of this site are only tested for access-rights. Contributions is therefore very much welcome.
If you want to change the database use follow the instruction for alembic
. Make
sure to adjust the definitions in muesli/models.py
.
To upgrade to the latest version of the database:
$ alemic upgrade head
To create new revisions use:
$ alembic revision -m "Added a column"
Don't add JS-libraries to the repository, instead add add them to the package.json file and let them be copied by the
Dockerfile. You can install new dependencies with apt
via the Dockerfile
, too.
To create or edit a page you can edit the template to change the visuals, to add
functions you edit the views*.py
file. In the .py
you can pass variables
to the template and write server-side logic.
You can also execute arbitrary python statements in the templates,
so dont underestimate their power.
Remember to add tests for all new pages!
For each class or function belonging to a page you need a decorator like this one:
@view_config(
route_name='admin',
renderer='muesli.web:templates/admin.pt',
context=GeneralContext,
permission='admin'
)
You set a name matching the name given in __init__.py
, the renderer is used
to set the corresponding template file. The context is important to control the
permissions and influences what is shown in the navigation. The permission
attribute is used to set the permission.
The permissions are granted in the context.py
file using the __acl__
attribute.
When changing permissions update them in muesli/web/navigation_tree.py
and the API as
necessary. Keep in mind that the API uses its own contexts and update them accordingly.
This means you cannot get the permission of a page dynamically and if you want to check for a permission you have to make sure the permission is granted in the specific context.
The navigation_tree is a tree-structure saved in the request object used for the navigation buttons at the top. When editing this tree make sure not to create any cycles, since these will crash the template-engine.
For every API endpoint there is a file in ./muesli/web/api/v1/
.
This file contains a class which represents the resource and behavior for the API.
To ensure the class recognized by cornice
it has the following decorator:
@resource(collection_path='/lectures',
path='/lectures/{lecture_id}',
factory=context.LectureEndpointContext)
class Lecture:
def __init__(self, request, context=None):
[...]
The classes are then added to the pyramid views in ./muesli/web/__init__.py
:
def main(global_config=None, testmode=False, **settings):
[...]
config.include('cornice')
[...]
If you want to add another endpoint, have a look at the code in
./muesli/web/api/v1/helloEndpoint.py
as it is a very simple endpoint to experiment with it.
Add a method for POST
or something else to get familiar with how things work.
It can also make sense to change the following value in ./muesli.yml.example
since it provides some tooling to analyze the framework.
development: False
Just tag Chris (@christian-heusel) or @Philipp-g in your corresponding issue or PR. 😄