groue / GRMustache.swift

Flexible Mustache templates for Swift
http://mustache.github.com/
MIT License
594 stars 155 forks source link

Is it Possible to passe text from template to a function? #91

Closed mackoj closed 1 year ago

mackoj commented 1 year ago

Hello, thank you for creating and maintaining GRMustache. I apologize for any inconvenience, but I have a question.

Is it possible, using GRMustache, to extract text from a template to pass it to a function? I've gone through the documentation, but I don't have the impression that it's feasible to provide a function with a parameter coming from the template rather than from the render method.

I've prepared a simplified example of what I'm trying to achieve. Do you think this would be possible?

func canThisBePossible() throws {
  let extractDataFromJSONFile = VariadicFilter { (boxes: [MustacheBox]) in
    guard let fromFile = boxes[0].value as? String
    else { throw "Failed to extract fromFile from boxes[0] = \(boxes[0].value)" }

    guard let jsonPath = boxes[1].value as? String
    else { throw "Failed to extract jsonPath from boxes[1] = \(boxes[1].value)" }

    guard let transformer = boxes[2].value as? String
    else { throw "Failed to extract transformer from boxes[2] = \(boxes[2].value)" }

    guard FileManager.default.fileExists(atPath: fromFile)
    else { throw "File \(fromFile) don't exist" }

    guard FileManager.default.isReadableFile(atPath: fromFile)
    else { throw "File \(fromFile) is not readable" }

    guard let dataTransformer = mapper[transformer]
    else { throw "Data transformer not found for key \(transformer)" }

    guard let loadFile = try? String(contentsOfFile: fromFile)
    else { throw "Failed to transform \(fromFile) data to a String" }

    // JSONPath data extraction using Sextant https://www.swift-linux.com/sextant/
    guard let extractedData = loadFile.query(paths: jsonPath)?.first as? String
    else { throw "Failed to find data from \(fromFile) at path \(jsonPath)" }

    return dataTransformer(extractedData)
  }

  let template = try Template(string: #"var backgroundColor: Color = {{ getToken("component/badge/ios.json", "$.vp.component.badge.primary.color.background.default.value", "Color") }}"#)
  template.register(extractDataFromJSONFile, forKey: "getToken")

  // var backgroundColor: Color = DesignTokens.Semantic.Color.containerHighlight"
  let rendering = try template.render()
}

func colorTransformer(_ input: String) -> String {
  "DesignTokens.Semantic.Color.containerHighlight"
}

let mapper: [String: (String) -> String] = [
  "Color": colorTransformer
]