mirror of
https://github.com/wrabit/django-cotton.git
synced 2025-08-03 14:48:17 +00:00
handle attributes containing quoted spaces
This commit is contained in:
parent
072342fae0
commit
12d64ede25
4 changed files with 90 additions and 5 deletions
|
@ -14,6 +14,4 @@ def index_view(request):
|
|||
)
|
||||
|
||||
|
||||
urlpatterns = [
|
||||
path("", index_view),
|
||||
]
|
||||
urlpatterns = [path("", index_view)]
|
||||
|
|
|
@ -7,7 +7,22 @@ class Tag:
|
|||
r"<(/?)c-([^\s/>]+)((?:\s+[^\s/>\"'=<>`]+(?:\s*=\s*(?:\"[^\"]*\"|'[^']*'|\S+))?)*)\s*(/?)\s*>",
|
||||
re.DOTALL,
|
||||
)
|
||||
attr_pattern = re.compile(r'([^\s/>\"\'=<>`]+)(?:\s*=\s*(?:(["\'])(.*?)\2|(\S+)))?', re.DOTALL)
|
||||
# attr_pattern = re.compile(r'([^\s/>\"\'=<>`]+)(?:\s*=\s*(?:(["\'])(.*?)\2|(\S+)))?', re.DOTALL)
|
||||
|
||||
attr_pattern = re.compile(
|
||||
r"""([^\s/>\"\'=<>`]+) # Attribute name
|
||||
(?: # Optional group for value
|
||||
\s*=\s* # Equals with optional whitespace
|
||||
(?:
|
||||
(["\']) # Quote character
|
||||
((?:(?!\2)|.)*?) # Any character that's not the quote character
|
||||
\2 # Matching quote
|
||||
| # OR
|
||||
(\S+) # Non-quoted value without spaces
|
||||
)
|
||||
)?""",
|
||||
re.VERBOSE | re.DOTALL,
|
||||
)
|
||||
|
||||
def __init__(self, match: re.Match):
|
||||
self.html = match.group(0)
|
||||
|
@ -130,7 +145,7 @@ class CottonCompiler:
|
|||
|
||||
if len(matches) > 1:
|
||||
raise ValueError(
|
||||
f"Multiple c-vars tags found in component template. Only one c-vars tag is allowed per template."
|
||||
"Multiple c-vars tags found in component template. Only one c-vars tag is allowed per template."
|
||||
)
|
||||
|
||||
# Process single c-vars tag if present
|
||||
|
|
|
@ -127,6 +127,57 @@ def cotton_component(parser, token):
|
|||
attrs = {}
|
||||
only = False
|
||||
|
||||
current_key = None
|
||||
current_value = []
|
||||
|
||||
for bit in bits[1:]:
|
||||
if bit == "only":
|
||||
only = True
|
||||
continue
|
||||
|
||||
if "=" in bit:
|
||||
# If we were building a previous value, store it
|
||||
if current_key:
|
||||
attrs[current_key] = " ".join(current_value)
|
||||
current_value = []
|
||||
|
||||
# Start new key-value pair
|
||||
key, value = bit.split("=", 1)
|
||||
if value.startswith(("'", '"')):
|
||||
if value.endswith(("'", '"')) and value[0] == value[-1]:
|
||||
# Complete quoted value
|
||||
attrs[key] = value
|
||||
else:
|
||||
# Start of quoted value
|
||||
current_key = key
|
||||
current_value = [value]
|
||||
else:
|
||||
# Simple unquoted value
|
||||
attrs[key] = value
|
||||
else:
|
||||
if current_key:
|
||||
# Continue building quoted value
|
||||
current_value.append(bit)
|
||||
else:
|
||||
# Boolean attribute
|
||||
attrs[bit] = True
|
||||
|
||||
# Store any final value being built
|
||||
if current_key:
|
||||
attrs[current_key] = " ".join(current_value)
|
||||
|
||||
nodelist = parser.parse(("endc",))
|
||||
parser.delete_first_token()
|
||||
|
||||
return CottonComponentNode(component_name, nodelist, attrs, only)
|
||||
|
||||
|
||||
def cotton_component_legacy(parser, token):
|
||||
bits = token.split_contents()[1:]
|
||||
component_name = bits[0]
|
||||
attrs = {}
|
||||
only = False
|
||||
|
||||
node_class = CottonComponentNode
|
||||
|
||||
for bit in bits[1:]:
|
||||
|
|
|
@ -511,3 +511,24 @@ class AttributeHandlingTests(CottonTestCase):
|
|||
response,
|
||||
"""attrs: ':string="variable" dynamic="Ive been resolved!" :complex-string="{'something': 1}" complex-dynamic="{'something': 1}"'""",
|
||||
)
|
||||
|
||||
def test_attributes_can_contain_valid_json(self):
|
||||
self.create_template(
|
||||
"cotton/json_attrs.html",
|
||||
"""
|
||||
<button {{ attrs }}>{{ slot }}</button>
|
||||
""",
|
||||
)
|
||||
|
||||
self.create_template(
|
||||
"json_attrs_view.html",
|
||||
"""
|
||||
<c-json-attrs data-something='{"key=dd": "the value with= spaces"}' />
|
||||
""",
|
||||
"view/",
|
||||
)
|
||||
|
||||
with self.settings(ROOT_URLCONF=self.url_conf()):
|
||||
response = self.client.get("/view/")
|
||||
|
||||
self.assertContains(response, """{"key=dd": "the value with= spaces"}""")
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue