From 90e3f8125dbe078108aa590cd8264532b86b738e Mon Sep 17 00:00:00 2001 From: RussBaz Date: Fri, 5 Apr 2024 00:01:35 +0500 Subject: [PATCH] Added am optional 'local-only' attribute to a r-reqired tag --- README.md | 1 + Resources/Pages/Components/hello-me.html | 4 +++- Resources/Pages/index.html | 2 +- Sources/Core/AST.swift | 2 +- Sources/Core/Parser.swift | 3 ++- Sources/Core/SwiftCodeGenerator.swift | 4 ++-- Sources/Core/SwiftPageSignatures.swift | 5 ++++- Sources/Example/pages.swift | 13 +++++++++---- 8 files changed, 23 insertions(+), 11 deletions(-) diff --git a/README.md b/README.md index eed97ec..c3ed236 100644 --- a/README.md +++ b/README.md @@ -175,6 +175,7 @@ Optionally, you can save the result of the condition to a different variable usi - **``** (must be before any tag other than r-require) to wrap the current template into a default slot of the specified template - **``** (must be before any tag other than r-extend) to define a variable that must be passed into the template from the caller - **``** or if you need to remap it to a mutable variable of the same name +- or you can add `local-only` attribute to prevent it from being required in outer scopes. You have to provide your own argument for such a parameter in such a case. - **``** to include another template or - **` default slot `** to include a template with a default slot provided - **` some data `** to group some part of template, e.g. wrap some text with it and now you can apply control attributes to it. diff --git a/Resources/Pages/Components/hello-me.html b/Resources/Pages/Components/hello-me.html index b0f3779..9eb9644 100644 --- a/Resources/Pages/Components/hello-me.html +++ b/Resources/Pages/Components/hello-me.html @@ -1 +1,3 @@ -Hello, Friend! + + +Hello, Friend! [extra name: \(name)] diff --git a/Resources/Pages/index.html b/Resources/Pages/index.html index 7613d08..f522fe1 100644 --- a/Resources/Pages/index.html +++ b/Resources/Pages/index.html @@ -24,7 +24,7 @@

  • - \(hero) + \(hero)

    Index: \(index)

  • diff --git a/Sources/Core/AST.swift b/Sources/Core/AST.swift index c9fabf6..2863562 100644 --- a/Sources/Core/AST.swift +++ b/Sources/Core/AST.swift @@ -9,7 +9,7 @@ public indirect enum AST { case conditional(name: String?, check: String, type: ConditionType, contents: ASTStorage) case loop(forEvery: String, name: String?, itemName: String, indexName: String, contents: ASTStorage) case modifiers(applying: [AttributeModifier], tag: TagType) - case requirement(name: String, type: String, label: String?, value: String?, mutable: Bool) + case requirement(name: String, type: String, label: String?, value: String?, mutable: Bool, localOnly: Bool) case eval(line: String) case value(of: String, defaultValue: String?) case assignment(name: String, line: String) diff --git a/Sources/Core/Parser.swift b/Sources/Core/Parser.swift index 2a2ea27..f79564b 100644 --- a/Sources/Core/Parser.swift +++ b/Sources/Core/Parser.swift @@ -414,8 +414,9 @@ extension Parser { let label = attributes.find("label") let defaultValue = attributes.find("default") let mutable = attributes.find("mutable") != nil + let localOnly = attributes.has("local-only") - ast.append(node: .requirement(name: name, type: type, label: label, value: defaultValue, mutable: mutable)) + ast.append(node: .requirement(name: name, type: type, label: label, value: defaultValue, mutable: mutable, localOnly: localOnly)) } func openSetTag(_ tag: AST.TagType, at depth: Int) { diff --git a/Sources/Core/SwiftCodeGenerator.swift b/Sources/Core/SwiftCodeGenerator.swift index c55c2f9..0ae2b09 100644 --- a/Sources/Core/SwiftCodeGenerator.swift +++ b/Sources/Core/SwiftCodeGenerator.swift @@ -418,8 +418,8 @@ public final class SwiftCodeGenerator { case .closingTag: properties.append("// Error: Impossible tag type", at: indentation) } - case let .requirement(name, type, label, value, mutable): - signatures.append(parameter: .init(type: type, name: name, label: label, defaultValue: value, canBeOverriden: false), to: properties.name) + case let .requirement(name, type, label, value, mutable, localOnly): + signatures.append(parameter: .init(type: type, name: name, label: label, defaultValue: value, canBeOverriden: false, localOnly: localOnly), to: properties.name) if mutable { properties.appendMutable(name: name) diff --git a/Sources/Core/SwiftPageSignatures.swift b/Sources/Core/SwiftPageSignatures.swift index 23065d0..9a74d92 100644 --- a/Sources/Core/SwiftPageSignatures.swift +++ b/Sources/Core/SwiftPageSignatures.swift @@ -5,6 +5,7 @@ public final class SwiftPageSignatures { let label: String? let defaultValue: String? let canBeOverriden: Bool + let localOnly: Bool } public struct PageSignature { @@ -157,7 +158,7 @@ extension SwiftPageSignatures { guard let cached = resolved[i] else { continue } for c in cached { - if !buffer.contains(where: { $0.name == c.name }) { + if !c.localOnly, !buffer.contains(where: { $0.name == c.name }) { buffer.append(c) } } @@ -197,6 +198,8 @@ extension SwiftPageSignatures.ParameterDef: LosslessStringConvertible { public init?(_ description: String) { let checkedDescription: String + localOnly = false + if description.starts(with: "?") { canBeOverriden = true checkedDescription = String(description.dropFirst()) diff --git a/Sources/Example/pages.swift b/Sources/Example/pages.swift index a7bb198..648c428 100644 --- a/Sources/Example/pages.swift +++ b/Sources/Example/pages.swift @@ -35,13 +35,15 @@ enum Pages { // Own pages enum HelloMe { // Template: ./Components/hello-me.html - static func render(req: Request) -> String { - include(req: req).render() + static func render(req: Request, name: String = "no-name") -> String { + include(req: req, name: name).render() } - static func include(req _: Request) -> SwiftLineStorage { + static func include(req _: Request, name: String = "no-name") -> SwiftLineStorage { let lines = SwiftLineStorage() lines.append(""" + + Hello, """) lines.declare(slot: "default") { lines in @@ -49,6 +51,9 @@ enum Pages { Friend! """) } + lines.append(""" + [extra name: \(name)] + """) return lines } @@ -240,7 +245,7 @@ enum Pages { attributes = SwiftAttributeStorage.from(attributes: ["class": .string("base", wrapper: .double)]) attributes.append(to: "class", value: .string(" rose", wrapper: .double)) lines.append("") - lines.include(Pages.Components.HelloMe.include(req: req)) { lines in + lines.include(Pages.Components.HelloMe.include(req: req, name: "very sad")) { lines in lines.append(""" \(hero) """)