Skip to content

Deferred static files #77

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 37 commits into from
Jul 1, 2022
Merged
Show file tree
Hide file tree
Changes from 10 commits
Commits
Show all changes
37 commits
Select commit Hold shift + click to select a range
51a473a
functional static_css implementation
Archmonger Jun 23, 2022
b1a2bcf
Bump Django IDOM version
Archmonger Jun 23, 2022
6b82359
format components.py
Archmonger Jun 23, 2022
551b6f1
rudimentary docs
Archmonger Jun 23, 2022
d5b0d9c
fix docstring
Archmonger Jun 23, 2022
11b3e42
clean up readme
Archmonger Jun 23, 2022
e9339fa
static_js
Archmonger Jun 23, 2022
836fe71
minor docs styling tweaks
Archmonger Jun 23, 2022
0ee9402
Update docs/features/components.md
Archmonger Jun 23, 2022
a19508f
Merge branch 'static-css' of https://github.com/Archmonger/django-ido…
Archmonger Jun 23, 2022
4cc86aa
flesh out the docs
Archmonger Jun 23, 2022
526bc8f
simplify _cached_static_contents
Archmonger Jun 23, 2022
6b0dfb8
add static js to changelog
Archmonger Jun 23, 2022
70d78fc
clean up changelog entry
Archmonger Jun 23, 2022
0ffb5a5
Selenium 4.3 compatibility
Archmonger Jun 23, 2022
6cc9ded
add title to readme example
Archmonger Jun 23, 2022
7733243
pin selenium to older version 4.2
Archmonger Jun 23, 2022
568a49e
Revert "Selenium 4.3 compatibility"
Archmonger Jun 23, 2022
5f981a0
add new tests
Archmonger Jun 24, 2022
f9aa39f
fix tests
Archmonger Jun 24, 2022
aa55ad7
docs cleanup
Archmonger Jun 24, 2022
fa11504
Create PR template
Archmonger Jun 24, 2022
03ac980
bump the minimum idom version
Archmonger Jun 24, 2022
7095f64
update issue form
Archmonger Jun 26, 2022
bdb3431
minor readme wordsmithing
Archmonger Jun 26, 2022
7ea6306
docstring for component template tag
Archmonger Jun 26, 2022
2de0dee
use PascalCase for component names
Archmonger Jun 28, 2022
1db08a5
Fix formatting
Archmonger Jun 28, 2022
1e26dfa
fix HR on JS test
Archmonger Jun 29, 2022
53ea6e6
wordsmith
Archmonger Jun 29, 2022
ad33221
fix spelling
Archmonger Jun 30, 2022
574acdb
Update tests/test_app/static/static-css-test.css
Archmonger Jul 1, 2022
aea5062
Update .github/ISSUE_TEMPLATE/issue-form.yml
Archmonger Jul 1, 2022
18dc658
Update tests/test_app/static/static-js-test.js
Archmonger Jul 1, 2022
2660882
use_memo is preferrable
Archmonger Jul 1, 2022
4412459
Merge branch 'static-css' of https://github.com/Archmonger/django-ido…
Archmonger Jul 1, 2022
a544c11
use snake_case
Archmonger Jul 1, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,12 @@ Types of changes are to be listed in this order

- Nothing (yet)

## [1.1.0] - 2022-06-25

### Added

- `static_css` component that can be used to defer loading CSS for your IDOM components until you need them.

## [1.0.0] - 2022-05-22

### Added
Expand Down Expand Up @@ -103,6 +109,7 @@ Types of changes are to be listed in this order
- Support for IDOM within the Django

[unreleased]: https://github.com/idom-team/django-idom/compare/1.0.0...HEAD
[1.1.0]: https://github.com/idom-team/django-idom/compare/1.0.0...1.1.0
[1.0.0]: https://github.com/idom-team/django-idom/compare/0.0.5...1.0.0
[0.0.5]: https://github.com/idom-team/django-idom/compare/0.0.4...0.0.5
[0.0.4]: https://github.com/idom-team/django-idom/compare/0.0.3...0.0.4
Expand Down
4 changes: 0 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,6 @@ Any Python web framework with Websockets can support IDOM. See below for what fr

<!--intro-end-->

---

# At a Glance

## `my_app/components.py`
Expand Down Expand Up @@ -65,8 +63,6 @@ Additonally, you can pass in keyword arguments into your component function. For

<!--html-code-end-->

---

# Resources

<!--resources-start-->
Expand Down
31 changes: 31 additions & 0 deletions docs/features/components.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
## Static CSS

Allows you to defer loading a CSS stylesheet until a component begins rendering. This stylesheet must be stored within [Django's static files](https://docs.djangoproject.com/en/dev/howto/static-files/).

```python title="components.py"
from idom import component, html
from django_idom.components import static_css

@component
def MyComponent():
return html.div(
static_css("/static/css/buttons.css"),
html.button("My Button!")
)
```

??? question "Should I put `static_css` at the top of my component?"

<!-- Yes, to ensure proper load order -->

??? question "Can I load HTML using `html.link`?"

??? question "What about external stylesheets?"

??? question "Why not load my CSS in `#!html <head>`?"

<!-- Generally, Django stylesheets are loaded in your `#!html <head>` using the `#!jinja {% load static %}` template tag. -->

## Static JavaScript

<!-- In progress -->
3 changes: 1 addition & 2 deletions docs/features/hooks.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ def MyComponent():
return html.div(my_websocket)
```

---


## Use Scope

Expand All @@ -34,7 +34,6 @@ def MyComponent():
return html.div(my_scope)
```

---

## Use Location

Expand Down
4 changes: 4 additions & 0 deletions docs/stylesheets/extra.css
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,7 @@
.md-header {
background-color: var(--md-footer-bg-color--dark);
}

.md-typeset :is(.admonition, details) {
margin: 1em 0;
}
1 change: 1 addition & 0 deletions mkdocs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ nav:
- 4. Render Your View: getting-started/render-view.md
- 5. Learn More: getting-started/learn-more.md
- Exclusive Features:
- Components: features/components.md
- Hooks: features/hooks.md
- Template Tag: features/templatetag.md
- Contribute:
Expand Down
6 changes: 3 additions & 3 deletions src/django_idom/__init__.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
from . import hooks
from . import components, hooks
from .websocket.consumer import IdomWebsocket
from .websocket.paths import IDOM_WEBSOCKET_PATH


__version__ = "1.0.0"
__all__ = ["IDOM_WEBSOCKET_PATH", "IdomWebsocket", "hooks"]
__version__ = "1.1.0"
__all__ = ["IDOM_WEBSOCKET_PATH", "IdomWebsocket", "hooks", "components"]
41 changes: 41 additions & 0 deletions src/django_idom/components.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import os

from django.contrib.staticfiles.finders import find
from idom import component, html

from django_idom.config import IDOM_CACHE


@component
def static_css(static_path: str):
"""Fetches a CSS static file for use within IDOM. This allows for deferred CSS loading."""
return html.style(_cached_static_contents(static_path, "css_contents"))


@component
def static_js(static_path: str):
"""Fetches a JS static file for use within IDOM. This allows for deferred JS loading."""
return html.script(_cached_static_contents(static_path, "js_contents"))


def _cached_static_contents(static_path: str, cache_name: str):
# Try to find the file within Django's static files
abs_path = find(static_path)
if not abs_path:
raise FileNotFoundError(
f"Could not find static file {static_path} within Django's static files."
)

# Fetch the file from cache, if available
last_modified_time = os.stat(abs_path).st_mtime
cache_key = f"django_idom:{cache_name}:{static_path}"
file_contents = IDOM_CACHE.get(cache_key, version=last_modified_time)
if file_contents is None:
with open(abs_path, encoding="utf-8") as static_file:
file_contents = static_file.read()
IDOM_CACHE.delete(cache_key)
IDOM_CACHE.set(
cache_key, file_contents, timeout=None, version=last_modified_time
)

return file_contents