Skip to content
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

Adds turbo_refreshes_with template tag for upcoming changes in Turbo 8 #20

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
21 changes: 21 additions & 0 deletions docs/source/morphing.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
## turbo_refreshes_with

This template tag generates HTML meta tags for Turbo Drive to control the refresh method and scroll behavior in Turbo 8.0+ ([currently in beta](https://github.com/hotwired/turbo/releases/tag/v8.0.0-beta.4)).

### Parameters

- `method` (optional, default: `'replace'`): Specifies the refresh method. Must be one of `'replace'` or `'morph'`.
- `scroll` (optional, default: `'reset'`): Specifies the scroll behavior. Must be one of `'reset'` or `'preserve'`.

### Behavior

This tag creates HTML meta tags defining the Turbo Frames' refresh method and scroll behavior based on the provided parameters. If the provided parameters are not within the valid options, a `ValidationError` is raised.

### Example Usage

```django
{% load turbo_helper %}

<!-- Generate Turbo Frames refresh meta tags -->
{% turbo_refreshes_with method='replace' scroll='reset' %}
```
18 changes: 18 additions & 0 deletions src/turbo_helper/templatetags/turbo_helper.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,9 @@
from django import template
from django.db.models.base import Model
from django.template import Node, TemplateSyntaxError
from django.core.exceptions import ValidationError
from django.template.base import token_kwargs
from django.utils.html import format_html

from turbo_helper.renderers import render_turbo_frame, render_turbo_stream_from
from turbo_helper.stream import action_proxy
Expand Down Expand Up @@ -260,3 +262,19 @@ def turbo_stream_from_tag(parser, token):
stream_name_array = [parser.compile_filter(bit) for bit in remaining_bits]

return TurboStreamFromTagNode(stream_name_array)


@register.simple_tag
def turbo_refreshes_with(method='replace', scroll='reset') -> str:
valid_methods = ['replace', 'morph']
valid_scrolls = ['reset', 'preserve']

if method not in valid_methods:
raise ValidationError(f"Invalid refresh option '{method}'")
if scroll not in valid_scrolls:
raise ValidationError(f"Invalid scroll option '{scroll}'")

meta_tags = f'<meta name="turbo-refresh-method" content="{method}">'
meta_tags += f'<meta name="turbo-refresh-scroll" content="{scroll}">'

return format_html(meta_tags)
35 changes: 35 additions & 0 deletions tests/test_tags.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import pytest
from django.core.exceptions import ValidationError
from django.template import Context, Template

from tests.testapp.models import TodoItem
Expand Down Expand Up @@ -169,3 +170,37 @@ def test_dom_id_variable(self):
output
== '<turbo-cable-stream-source channel="TurboStreamCableChannel" signed-stream-name="test_todo_3:7ZS0MxQWhRTCAnG3olGO9AJKfvos3iaHGoBMBt8ZbSM"></turbo-cable-stream-source>'
)


class TestRefreshesWith:
def test_turbo_refreshes_with_tag(self):
template = """
{% load turbo_helper %}

{% turbo_refreshes_with method='replace' scroll='reset' %}
"""

output = render(template, {}).strip()

expected_method_tag = '<meta name="turbo-refresh-method" content="replace">'
expected_scroll_tag = '<meta name="turbo-refresh-scroll" content="reset">'

assert expected_method_tag in output
assert expected_scroll_tag in output

def test_invalid_options(self):
with pytest.raises(ValidationError):
template = """
{% load turbo_helper %}

{% turbo_refreshes_with method='invalid' scroll='reset' %}
"""
output = render(template, {}).strip()

with pytest.raises(ValidationError):
template = """
{% load turbo_helper %}

{% turbo_refreshes_with method='replace' scroll='invalid' %}
"""
output = render(template, {}).strip()
Loading