Skip to content

Commit 628b7c0

Browse files
committed
Added docs for static files
1 parent 0e50cc5 commit 628b7c0

File tree

4 files changed

+107
-17
lines changed

4 files changed

+107
-17
lines changed

docs/basics/execution-context.md

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ This allows different components of the application like **exception handlers**,
77
There are two class `HostContext` and `ExecutionContext` which provides set of methods and properties for accessing and manipulating the current context of execution.
88

99

10-
## HostContext
10+
## **HostContext**
1111
The `HostContext` class provides a wrapper around `ASGI` app parameters (`scope`, `receive` and `send`) and provides some methods that allows you choosing the appropriate context(e.g., HTTP or WebSockets).
1212

1313
For example, the `catch()` method of an **exception handlers** is called with an IHostContext.
@@ -44,7 +44,7 @@ class MyCustomExceptionHandler(IExceptionHandler):
4444

4545
```
4646

47-
## Switching to other Contexts
47+
## **Switching to other Contexts**
4848

4949
Currently, in Ellar you can only switch between `http` and `websocket` context. And each context has `get_client` method that returns context session.
5050

@@ -141,7 +141,7 @@ class IWebSocketConnectionHost(ABC):
141141
"""Returns WebSocket instance"""
142142
```
143143

144-
## ExecutionContext Class
144+
## **ExecutionContext Class**
145145
`ExecutionContext` extends `HostContext` and provides extra information like `Controller` class and controller `function`
146146
that will handler the current request.
147147

@@ -189,7 +189,7 @@ In this example, the `get_user` method is decorated with the `@get` decorator to
189189

190190
Once you have access to the `ExecutionContext` object, you can use its methods and properties to access information about the current request.
191191

192-
## Reflector and Metadata
192+
## **Reflector and Metadata**
193193
Ellar provides the ability to attach **custom metadata** to route handlers through the `@set_metadata()` decorator.
194194
We can then access this metadata from within our class to make certain decisions.
195195

docs/overview/module-router.md

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ ModuleRouter allows you to define your route handlers as standalone functions, p
44
This can be beneficial for python developers who prefer using functions.
55
It is important to note that using ModuleRouter does not limit your access to other features provided by Ellar.
66

7-
## Usage
7+
## **Usage**
88
The Ellar CLI tool generates a `routers.py` file in every `create-module` scaffold command.
99
This file contains a quick guide on how to use the `ModuleRouter` class.
1010

@@ -40,7 +40,7 @@ Each route takes two query parameters, 'a' and 'b' which are declared as int typ
4040

4141
Next, we have to make the `math_router` visible to the application
4242

43-
## Registering Module Router
43+
## **Registering Module Router**
4444
Like controllers, ModuleRouters also need to be registered to their root module in order to be used in a web application.
4545
In the example provided above, the `math_router` would be registered under the `project_name/apps/dogs/module.py` file.
4646

@@ -72,7 +72,7 @@ class DogsModule(ModuleBase):
7272
![math_router.png](../img/math_router.png)
7373

7474

75-
## Accessing Other Request Object
75+
## **Accessing Other Request Object**
7676
In functional route handle, we can access request object and response object through custom decorators or type annotation as shown below.
7777

7878
### By Type Annotation
@@ -92,7 +92,7 @@ def addition(request: Request, res: Response, a:int, b:int):
9292

9393
```
9494

95-
- By Custom decorators
95+
### **By Custom decorators**
9696
You can also achieve the same result by using custom decorator.
9797

9898
```python
@@ -111,7 +111,7 @@ def addition(*, request=Req(), res=Res(), a:int, b:int):
111111

112112
![math_router_with_request_object.png](../img/math_router_with_request_object.png)
113113

114-
## Inject Services
114+
## **Inject Services**
115115
We can also inject service providers just like controller routes using the `Provide` function.
116116

117117
```python

docs/templating/staticfiles.md

Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
A static file is a type of file that does not change often and is not generated by a server-side script. Examples of static files include images, CSS and JavaScript files, audio and video files, and other types of media.
2+
3+
Static files in Ellar are served using the `StaticFiles` ASGI class, which is an extension of the Starlette `StaticFiles` ASGI class.
4+
This class uses the static files specified in the application's **modules** and **configuration**.
5+
6+
In addition, Ellar creates a route that mounts the static server at the `/static` path.
7+
The path can be modified by providing a new value for the `STATIC_MOUNT_PATH` configuration variable.
8+
9+
## **Configuring static files**
10+
11+
1. In your config file, define `STATIC_MOUNT_PATH`, for example:
12+
```python
13+
14+
class Config:
15+
STATIC_MOUNT_PATH = '/static'
16+
```
17+
18+
2. Store your static files in a folder called **static** in your module. For example **my_module/static/my_module/example.jpg**.
19+
3. In your templates, use the `url_for` with `static` and `path` parameter to build the URL for the given relative path using the configured in `STATIC_DIRECTORIES`, `STATIC_FOLDER_PACKAGES` or Module.
20+
```html
21+
<img src="{{url_for('static', path='my_module/example.jpg')}}" alt="My image">
22+
```
23+
OR, visit `/static/my_app/example.jpg`
24+
25+
26+
## **Static File in Modules**
27+
28+
Managing multiple sets of static files in larger projects can be challenging,
29+
but by organizing each set of static files within a specific module,
30+
it becomes easier to manage and maintain.
31+
This approach allows for clear organization and separation of static assets,
32+
making it more manageable in a large project.
33+
34+
In our previous project, within the `dogs` module folder, we can create a following directories, `my_static/dogs`.
35+
Inside this folder `my_static/dogs`, we can create a file named `example.txt`.
36+
This allows us to keep all of the static files related to the dogs module organized in one location `my_static`.
37+
38+
Next, we tell `DogModule` about our static folder.
39+
40+
```python
41+
# project_name/apps/dogs/module.py
42+
43+
from ellar.common import Module
44+
from ellar.core import ModuleBase
45+
from ellar.di import Container
46+
47+
from .controllers import DogsController
48+
49+
50+
@Module(
51+
controllers=[DogsController], static_folder='my_static'
52+
)
53+
class DogsModule(ModuleBase):
54+
def register_providers(self, container: Container) -> None:
55+
# for more complicated provider registrations
56+
# container.register_instance(...)
57+
pass
58+
```
59+
60+
## **Other Static Configurations**
61+
In addition to setting static directories within modules,
62+
it is also possible to manually specify additional static directories that are not located within a module by using the
63+
`STATIC_FOLDER_PACKAGES` and `STATIC_DIRECTORIES` variables in the application's configuration.
64+
These variables allow for even more flexibility in organizing and managing static files in a project.
65+
These directories will be served by the StaticFiles ASGI class along with the module-scoped static files.
66+
67+
### `STATIC_DIRECTORIES`
68+
`STATIC_DIRECTORIES` variable is a list of directories within the project that contain static files.
69+
These directories are not necessarily scoped to a specific module and can be used to serve static files from any location within the project.
70+
These directories can be added to the `STATIC_DIRECTORIES` list in the application's configuration.
71+
72+
```python
73+
STATIC_DIRECTORIES = ['project_name/static-files', 'project_name/path/to/static/files']
74+
```
75+
76+
### `STATIC_FOLDER_PACKAGES`
77+
`STATIC_FOLDER_PACKAGES` variable is a list of tuples that contain python packages that hold some static files.
78+
These packages should have a `static` folder and the **package name** should be passed as tuple `(package_name, package_path)`,
79+
**package_path** is the relative path of static folder.
80+
81+
```python
82+
83+
STATIC_FOLDER_PACKAGES = [('bootstrap', 'statics'), ('package-name', 'path/to/static/directory')]
84+
```
85+
86+
Static files will respond with "404 Not found" or "405 Method not allowed" responses for requests which do not match. In `HTML` mode if `404.html` file exists it will be shown as 404 response.

docs/templating/templating.md

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,11 @@ In Ellar, a Model-View-Controller (MVC) framework, Jinja2 templates are typicall
55
while the Model and Controller layers handle the data and logic of the application.
66

77

8-
## Installation
8+
## **Installation**
99
[`Jinja2`](https://jinja.palletsprojects.com/en/3.0.x/) package is installed alongside with Ellar.
1010

1111

12-
## Quick overview on jinja2 Usage
12+
## **Quick overview on jinja2 Usage**
1313
A Jinja2 template is a plain text file that contains dynamic content, represented using Jinja2 syntax.
1414
Here's an example template that displays a list of items:
1515

@@ -71,7 +71,7 @@ and returns the rendered template as the `HTTP` response to the request.
7171
This example also shows manual setup of using `jinja2` in Ellar.
7272

7373

74-
## Jinja2 usage in Ellar
74+
## **Jinja2 usage in Ellar**
7575

7676
In Ellar, we use the `@render` decorator to convert the responses returned by the view to a Templated Response by creating an `HTMLResponseModel` with a status code of 200 to handle the response.
7777
Also, each registered `Module` is a `TemplateLoader` for loading templates available at `templates_folder`. And, a `Module` TemplateLoader object is created when the `template_folder` folder exists.
@@ -175,10 +175,10 @@ if __name__ == "__main__":
175175
- [`Starlette Recommendation`](https://www.starlette.io/templates/#asynchronous-template-rendering)
176176

177177

178-
## Jinja2 Configurations
178+
## **Jinja2 Configurations**
179179
If there are specific configurations you want to apply to your Jinja2 Environment, you can look at [JINJA_TEMPLATE_OPTIONS](https://eadwincode.github.io/ellar/configurations/#jinja_templates_options) configuration.
180180

181-
## Default Jinja Template Context
181+
## **Default Jinja Template Context**
182182

183183
Every jinja template in ellar receives two context, `url_for`, `config`, `request` object and other specific context defined to render a template.
184184

@@ -187,7 +187,7 @@ Every jinja template in ellar receives two context, `url_for`, `config`, `reques
187187
- `request` is current request object.
188188

189189

190-
## Static Files
190+
## **Static Files In Template**
191191

192192
As stated above, you can resolve file paths to static files using `url_for`.
193193

@@ -205,7 +205,7 @@ The `url_for` takes `path` parameter, in the case of `static` files, to match th
205205
This `url_for('static', path='img/Icon.svg')` will search for `img/Icon.svg` in all registered static folders.
206206

207207

208-
### Reversing Controllers URL
208+
### Reversing Controllers URLs
209209
It is common to need to generate URLs for specific routes, particularly when returning a redirect response.
210210
This can be achieved by using the `request.url_for` method in the request object, or in the case of templating, by using the `url_for()` function.
211211

@@ -285,7 +285,7 @@ we can see that the `parameter_a` is used as a keyword argument to satisfy the d
285285
If the `url_for` function is called with a path that does not exist or with insufficient parameters to resolve an existing URL,
286286
it will raise a `starlette.routing.NoMatchFound` exception.
287287

288-
### Module Router
288+
### Reversing Module Router URLs
289289

290290
Just like in controller, we can also reverse URLs that belongs to `ModuleRouter`.
291291

@@ -356,3 +356,7 @@ In this case, when reversing the URL, you would use `request.url_for('users:user
356356
which will generate `http://127.0.0.1:5000/template-reversing/profile/value_of_user_id` based on routing configuration.
357357

358358
This allows for greater control and readability when reversing URLs, and makes it less prone to error if the function name of the route were to change in the future.
359+
360+
361+
### Adding template filters and template globals.
362+
Jinja template filter and global functions can be defined at module level as shown here: [Module Templating Filters](../overview/modules/#module-templating-filters)

0 commit comments

Comments
 (0)