{"id":13872185,"url":"https://github.com/Apodini/ApodiniLeaf","last_synced_at":"2025-07-16T01:33:13.075Z","repository":{"id":40580547,"uuid":"371102138","full_name":"Apodini/ApodiniLeaf","owner":"Apodini","description":"ApodiniLeaf","archived":false,"fork":false,"pushed_at":"2022-11-01T01:58:14.000Z","size":166,"stargazers_count":2,"open_issues_count":0,"forks_count":0,"subscribers_count":5,"default_branch":"develop","last_synced_at":"2024-08-06T23:51:42.957Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"http://apodini.github.io/ApodiniLeaf/","language":"Swift","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Apodini.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSES/MIT.txt","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2021-05-26T16:32:54.000Z","updated_at":"2022-01-02T13:12:01.000Z","dependencies_parsed_at":"2023-01-21T00:16:14.710Z","dependency_job_id":null,"html_url":"https://github.com/Apodini/ApodiniLeaf","commit_stats":null,"previous_names":[],"tags_count":6,"template":false,"template_full_name":"Apodini/Template-Repository","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Apodini%2FApodiniLeaf","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Apodini%2FApodiniLeaf/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Apodini%2FApodiniLeaf/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Apodini%2FApodiniLeaf/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Apodini","download_url":"https://codeload.github.com/Apodini/ApodiniLeaf/tar.gz/refs/heads/develop","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":226090030,"owners_count":17572114,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-08-05T23:00:36.063Z","updated_at":"2024-11-23T19:31:40.108Z","avatar_url":"https://github.com/Apodini.png","language":"Swift","funding_links":[],"categories":["Swift"],"sub_categories":[],"readme":"\u003c!--\n                  \nThis source file is part of the Apodini Leaf open source project\n\nSPDX-FileCopyrightText: 2021 Paul Schmiedmayer and the project authors (see CONTRIBUTORS.md) \u003cpaul.schmiedmayer@tum.de\u003e\n\nSPDX-License-Identifier: MIT\n             \n--\u003e\n\n# Apodini Leaf\n\n[![DOI](https://zenodo.org/badge/371102138.svg)](https://zenodo.org/badge/latestdoi/371102138)\n[![codecov](https://codecov.io/gh/Apodini/ApodiniLeaf/branch/develop/graph/badge.svg?token=Rd38F6yTCC)](https://codecov.io/gh/Apodini/ApodiniLeaf)\n[![jazzy](https://raw.githubusercontent.com/Apodini/ApodiniLeaf/gh-pages/badge.svg)](https://apodini.github.io/ApodiniLeaf/)\n[![Build and Test](https://github.com/Apodini/ApodiniLeaf/actions/workflows/build-and-test.yml/badge.svg)](https://github.com/Apodini/ApodiniLeaf/actions/workflows/build-and-test.yml)\n\nApodini Leaf is a small [Apodini](https://github.com/Apodini/Apodini) extension to support the [Leaf](https://github.com/vapor/leaf-kit) teamplating engine.\nThe [Leaf documentation](https://docs.vapor.codes/4.0/leaf/overview/) provides a good overview of the usage of Leaf.\n\n## Integrate Swift Package\n\nTo use Apodini Leaf you have to add it as a depenency to your Swift Package in your Package.swift file. As Apodini Leaf is extending [Apodini](https://github.com/Apodini/Apodini) it is also currenlty using 0.X releases and every minor version number increment could include breaking changes. Therefore using `.upToNextMinor(from: \"0.1.0\")` is advised:\n```swift\ndependencies: [\n    .package(url: \"https://github.com/Apodini/ApodiniLeaf.git\", .upToNextMinor(from: \"0.1.0\")),\n    // More package dependencies ...\n]\n```\nNext add ApodiniLeaf as a target dependency to your web service target:\n```swift\n.target(\n    name: \"MyWebService\",\n    dependencies: [\n        .product(name: \"Apodini\", package: \"Apodini\"),\n        .product(name: \"ApodiniLeaf\", package: \"ApodiniLeaf\"),\n        // More target dependencies ...\n    ]\n)\n```\nNow you can import ApodiniLeaf in your web service:\n```swift\nimport ApodiniLeaf\n```\n\n## Usage\n\nTo use ApodiniLeaf, you have to define a `LeafConfiguration` in your `WebService` instance. You can pass in a `Bundle` or absolute path.\nIn this example we have defined [Swift Package resources using the resources definition](https://developer.apple.com/documentation/swift_packages/bundling_resources_with_a_swift_package) in our Package.Swift file:\n```swift\n.testTarget(\n    name: \"MyWebService\",\n    dependencies: [\n        // ...\n    ],\n    resources: [\n        .process(\"Resources\")\n    ]\n)\n```\n\nThe folder structure looks like follows:\n```\nMyWebService\n├── Package.swift\n├── Resources\n│   ├── Example.leaf\n└── Sources\n    └── ...\n```\n\nThe example Leaf file has the following content:\n```html\n\u003ctitle\u003e#(title)\u003c/title\u003e\n\u003cbody\u003e#(body)\u003c/body\u003e\n```\n\nWe use the `Bundle.module` to access the created resources bundle in the `WebService` configuration to configure the `LeafRenderer` as follows:\n```swift\nstruct TestWebService: WebService {\n    var configuration: Configuration {\n        LeafConfiguration(Bundle.module)\n    }\n    \n    var content: some Component {\n        Text(\"Test\")\n    }\n}\n```\n\nNow that we have defined the configuration, we can use the `LeafRenderer` in our Apodini `Handlers` using the `@Environment` property wrapper:\n```swift\nstruct ExampleHandler: Handler {\n    @Environment(\\.leafRenderer) var leafRenderer: LeafRenderer\n    \n    \n    func handle() -\u003e some ResponseTransformable {\n        struct ExampleContent: Encodable {\n            let title: String\n            let body: String\n        }\n        \n        let content = ExampleContent(title: \"Paul\", body: \"Hello!\")\n        return leafRenderer.render(path: \"Example\", context: content)\n    }\n}\n```\nThe `ExampleHandler` uses the `@Environment` property wrapper to retrieve the `LeafRenderer` and uses a Swift `struct` to fill in the content and renders the HTML using the `LeafRenderer`'s `render(path:context:)` method. For more information about Leaf, please refer to the [Leaf documentation](https://docs.vapor.codes/4.0/leaf/overview/).\n\n## Contributing\nContributions to this project are welcome. Please make sure to read the [contribution guidelines](https://github.com/Apodini/.github/blob/main/CONTRIBUTING.md) and the [contributor covenant code of conduct](https://github.com/Apodini/.github/blob/main/CODE_OF_CONDUCT.md) first.\n\n## License\nThis project is licensed under the MIT License. See [License](https://github.com/Apodini/ApodiniLeaf/blob/develop/LICENSE) for more information.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FApodini%2FApodiniLeaf","html_url":"https://awesome.ecosyste.ms/projects/github.com%2FApodini%2FApodiniLeaf","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FApodini%2FApodiniLeaf/lists"}