From 28ddab73988304f4a7befce4c5eb1d31c9a316ad Mon Sep 17 00:00:00 2001 From: Brian Sharon Date: Sat, 16 Mar 2024 12:55:09 -0600 Subject: [PATCH 1/7] Add library lint job --- .github/workflows/arduino_lint.yml | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) create mode 100644 .github/workflows/arduino_lint.yml diff --git a/.github/workflows/arduino_lint.yml b/.github/workflows/arduino_lint.yml new file mode 100644 index 0000000..2dd07de --- /dev/null +++ b/.github/workflows/arduino_lint.yml @@ -0,0 +1,24 @@ +name: Arduino Lint + +on: + push: + branches: + - main + pull_request: + +# The concurrency spec means that we'll only run one set of jobs per pull request or push to main. +# If a new push or pull request comes in while a job is running, all jobs in the concurrency group will be cancelled. +concurrency: + group: arduino-lint-${{ github.head_ref || github.run_id }} + cancel-in-progress: true + +jobs: + lint: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: arduino/arduino-lint-action@v1 + with: + compliance: strict + library-manager: submit + project-type: library \ No newline at end of file From 85ee02615f6548cbc71f6d30f0324ef60c39a40a Mon Sep 17 00:00:00 2001 From: Brian Sharon Date: Sat, 16 Mar 2024 13:03:05 -0600 Subject: [PATCH 2/7] library props --- library.properties | 12 ++++++++++++ 1 file changed, 12 insertions(+) create mode 100644 library.properties diff --git a/library.properties b/library.properties new file mode 100644 index 0000000..01a3463 --- /dev/null +++ b/library.properties @@ -0,0 +1,12 @@ +name=Ministache +version=1.0.0 +author=Brian Sharon +maintainer=Brian Sharon +sentence=Implementation of the Mustache templating language for Arduino +paragraph=Ministache is a small, fast and complete implementation of the Mustache templating language for Arduino. +category=Data Processing +url=https://github.com/floatplane/ministache +architectures=* +includes=ministache.hpp +depends=ArduinoJson (>=7.0.0) + From 6ffd721280d2117aa16dc5e3742b81430bd5fd5e Mon Sep 17 00:00:00 2001 From: Brian Sharon Date: Sat, 16 Mar 2024 13:31:46 -0600 Subject: [PATCH 3/7] Add a basic example and a keywords file --- examples/basic/basic.ino | 32 ++++++++++++++++++++++++++++++++ keywords.txt | 2 ++ 2 files changed, 34 insertions(+) create mode 100644 examples/basic/basic.ino create mode 100644 keywords.txt diff --git a/examples/basic/basic.ino b/examples/basic/basic.ino new file mode 100644 index 0000000..7998e25 --- /dev/null +++ b/examples/basic/basic.ino @@ -0,0 +1,32 @@ +#include + +/*************************************************** + This is a very basic example for the ministache library + (https://github.com/floatplane/ministache). + + It shows how the library can be used to render a Mustache template with a JSON object. + + For more details on Mustache syntax, see http://mustache.github.io/mustache.5.html + ****************************************************/ + +void setup() { + Serial.begin(9600); + + // Create a JSON object to hold the data that we'll use in our template + JsonDocument data; + data["name"] = "World"; + data["value"] = 42; + + // Create a template string + String templateString = "Hello, {{name}}! The answer is {{value}}."; + + // Render the template with the data + String output = ministache::render(templateString, data); + + // Print the result + Serial.println(output); // Prints: Hello, World! The answer is 42. +} + +void loop() { + delay(500); +} diff --git a/keywords.txt b/keywords.txt new file mode 100644 index 0000000..2fe3331 --- /dev/null +++ b/keywords.txt @@ -0,0 +1,2 @@ +ministache KEYWORD1 +render KEYWORD2 \ No newline at end of file From f1c3fe31ab147c27156caa4f38c18c1034e4617c Mon Sep 17 00:00:00 2001 From: Brian Sharon Date: Sat, 16 Mar 2024 13:34:11 -0600 Subject: [PATCH 4/7] Use actual tabs in keywords.txt --- keywords.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/keywords.txt b/keywords.txt index 2fe3331..8c1abab 100644 --- a/keywords.txt +++ b/keywords.txt @@ -1,2 +1,2 @@ -ministache KEYWORD1 -render KEYWORD2 \ No newline at end of file +ministache KEYWORD1 +render KEYWORD2 From 1f6a70f8ebe570e0ff9d26161c9f0b54d31fa6dc Mon Sep 17 00:00:00 2001 From: Brian Sharon Date: Sat, 16 Mar 2024 14:00:10 -0600 Subject: [PATCH 5/7] Update examples --- examples/basic/basic.ino | 3 +- examples/partials/partials.ino | 55 ++++++++++++++++++++++++++++++++++ 2 files changed, 57 insertions(+), 1 deletion(-) create mode 100644 examples/partials/partials.ino diff --git a/examples/basic/basic.ino b/examples/basic/basic.ino index 7998e25..a4e3568 100644 --- a/examples/basic/basic.ino +++ b/examples/basic/basic.ino @@ -10,7 +10,8 @@ ****************************************************/ void setup() { - Serial.begin(9600); + Serial.begin(115200); + Serial.println(""); // Create a JSON object to hold the data that we'll use in our template JsonDocument data; diff --git a/examples/partials/partials.ino b/examples/partials/partials.ino new file mode 100644 index 0000000..31f6d95 --- /dev/null +++ b/examples/partials/partials.ino @@ -0,0 +1,55 @@ +#include + +/*************************************************** + This is a very basic example for the ministache library + (https://github.com/floatplane/ministache). + + It shows how the library can be used to render a Mustache template with a JSON object. + + For more details on Mustache syntax, see http://mustache.github.io/mustache.5.html + ****************************************************/ + +void setup() { + Serial.begin(115200); + Serial.println(""); + + // Create a JSON object to hold the data that we'll use in our template. It looks like this: + // { + // "Alice": { + // "name": "Alice", + // "role": "Engineer" + // }, + // "Bob": { + // "name": "Bob", + // "role": "Intern" + // } + // } + JsonDocument data; + auto people = data["people"].to(); + auto alice = people.add(); + alice["name"] = "Alice"; + alice["role"] = "Engineer"; + auto bob = people.add(); + bob["name"] = "Bob"; + bob["role"] = "Intern"; + + // Create a template string that renders the data for a single person. This is a partial. + String personString = "Name: {{name}}\tRole: {{role}}\n"; + + // Create a template string that renders the data for all people. This is the main template. + String reportString = "People report:\n{{#people}}{{> person}}{{/people}}"; + + // Render the template with the data. The third argument is the partials list. This + // defines how to map a partial reference like {{>person }} to a particular template (personString). + String output = ministache::render(reportString, data, {{"person", personString}}); + + // Print the result + Serial.println(output); + // People report: + // Name: Alice Role: Engineer + // Name: Bob Role: Intern +} + +void loop() { + delay(500); +} From 7038ecaf3d02415714d1f11f8d1966b23edb2039 Mon Sep 17 00:00:00 2001 From: Brian Sharon Date: Sat, 16 Mar 2024 14:12:50 -0600 Subject: [PATCH 6/7] Cleanup README, rename header and source file --- README.md | 15 +++++++++++++-- examples/basic/basic.ino | 2 +- examples/partials/partials.ino | 5 +++-- library.properties | 2 +- src/{ministache.cpp => Ministache.cpp} | 2 +- src/{ministache.hpp => Ministache.h} | 0 test/ministache.cpp | 2 +- 7 files changed, 20 insertions(+), 8 deletions(-) rename src/{ministache.cpp => Ministache.cpp} (99%) rename src/{ministache.hpp => Ministache.h} (100%) diff --git a/README.md b/README.md index 351b337..9b1555e 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,4 @@ +[![.github/workflows/arduino_lint.yml](https://github.com/floatplane/ministache/actions/workflows/arduino_lint.yml/badge.svg)](https://github.com/floatplane/ministache/actions/workflows/arduino_lint.yml) [![.github/workflows/build.yml](https://github.com/floatplane/ministache/actions/workflows/build.yml/badge.svg)](https://github.com/floatplane/ministache/actions/workflows/build.yml) [![.github/workflows/test.yml](https://github.com/floatplane/ministache/actions/workflows/test.yml/badge.svg)](https://github.com/floatplane/ministache/actions/workflows/test.yml) [![.github/workflows/static_analysis.yml](https://github.com/floatplane/ministache/actions/workflows/static_analysis.yml/badge.svg)](https://github.com/floatplane/ministache/actions/workflows/static_analysis.yml) @@ -5,7 +6,7 @@ # Ministache -A spec-complete implementation of the [Mustache](https://mustache.github.io/) templating language for Arduino. +A spec-complete implementation of the [Mustache](https://mustache.github.io/) templating language for Arduino. A sane alternative to building up complex strings via concatenation and custom code. Very useful for embedded web servers! ## Features @@ -20,7 +21,7 @@ Complete support for all elements of the [Mustache core specification](https://g See the [mustache documentation](https://mustache.github.io/mustache.5.html) for more details on these features. -## Example +## Basics ```c++ ArduinoJson::JsonDocument data; @@ -28,3 +29,13 @@ data[F("subject")] = F("world"); const String output = ministache::render(F("Hello, {{subject}}!"), data); Serial.println(output); // Hello, world! ``` + +See [basic.ino](examples/basic/basic.ino) for a sketch demonstrating basic Ministache usage. + +## Partials + +Partials are a powerful Mustache feature allow you to define a chunk of template code and use it in a loop. See [partials.ino](examples/partials/partials.ino) for a sketch demonstrating how to use partials with Ministache. + +## Projects using Ministache + +- [floatplane/mitsubishi2MQTT](https://github.com/floatplane/mitsubishi2MQTT) \ No newline at end of file diff --git a/examples/basic/basic.ino b/examples/basic/basic.ino index a4e3568..5d103bd 100644 --- a/examples/basic/basic.ino +++ b/examples/basic/basic.ino @@ -1,4 +1,4 @@ -#include +#include /*************************************************** This is a very basic example for the ministache library diff --git a/examples/partials/partials.ino b/examples/partials/partials.ino index 31f6d95..e88848d 100644 --- a/examples/partials/partials.ino +++ b/examples/partials/partials.ino @@ -1,4 +1,4 @@ -#include +#include /*************************************************** This is a very basic example for the ministache library @@ -40,7 +40,8 @@ void setup() { String reportString = "People report:\n{{#people}}{{> person}}{{/people}}"; // Render the template with the data. The third argument is the partials list. This - // defines how to map a partial reference like {{>person }} to a particular template (personString). + // defines how to map a partial reference like {{>person }} to a particular template + // (personString). String output = ministache::render(reportString, data, {{"person", personString}}); // Print the result diff --git a/library.properties b/library.properties index 01a3463..97b36ce 100644 --- a/library.properties +++ b/library.properties @@ -7,6 +7,6 @@ paragraph=Ministache is a small, fast and complete implementation of the Mustach category=Data Processing url=https://github.com/floatplane/ministache architectures=* -includes=ministache.hpp +includes=Ministache.h depends=ArduinoJson (>=7.0.0) diff --git a/src/ministache.cpp b/src/Ministache.cpp similarity index 99% rename from src/ministache.cpp rename to src/Ministache.cpp index caae55b..49ae0cd 100644 --- a/src/ministache.cpp +++ b/src/Ministache.cpp @@ -1,5 +1,5 @@ -#include "ministache.hpp" +#include "Ministache.h" #include #include diff --git a/src/ministache.hpp b/src/Ministache.h similarity index 100% rename from src/ministache.hpp rename to src/Ministache.h diff --git a/test/ministache.cpp b/test/ministache.cpp index 0b3909c..43d3bdf 100644 --- a/test/ministache.cpp +++ b/test/ministache.cpp @@ -1,6 +1,6 @@ #define DOCTEST_CONFIG_IMPLEMENT // REQUIRED: Enable custom main() -#include "ministache.hpp" +#include "Ministache.h" #include #include From 735aed2e4093e32b2b7e5b6ee1ef6a2de22f6df7 Mon Sep 17 00:00:00 2001 From: Brian Sharon Date: Sat, 16 Mar 2024 15:16:11 -0600 Subject: [PATCH 7/7] Update library definitions, update example comments --- examples/basic/basic.ino | 8 ++++-- examples/partials/partials.ino | 51 +++++++++++++++++----------------- library.json | 39 ++++++++++++++++++++++++++ library.properties | 2 +- 4 files changed, 72 insertions(+), 28 deletions(-) create mode 100644 library.json diff --git a/examples/basic/basic.ino b/examples/basic/basic.ino index 5d103bd..238c439 100644 --- a/examples/basic/basic.ino +++ b/examples/basic/basic.ino @@ -13,7 +13,7 @@ void setup() { Serial.begin(115200); Serial.println(""); - // Create a JSON object to hold the data that we'll use in our template + // Create a JsonDocument instance to hold the data that we'll use in our template JsonDocument data; data["name"] = "World"; data["value"] = 42; @@ -25,7 +25,11 @@ void setup() { String output = ministache::render(templateString, data); // Print the result - Serial.println(output); // Prints: Hello, World! The answer is 42. + Serial.println(output); + + // Expected output: + // + // Hello, World! The answer is 42. } void loop() { diff --git a/examples/partials/partials.ino b/examples/partials/partials.ino index e88848d..7a3c612 100644 --- a/examples/partials/partials.ino +++ b/examples/partials/partials.ino @@ -1,11 +1,9 @@ #include /*************************************************** - This is a very basic example for the ministache library + This is an example of how to use Mustache partials with the Ministache library (https://github.com/floatplane/ministache). - It shows how the library can be used to render a Mustache template with a JSON object. - For more details on Mustache syntax, see http://mustache.github.io/mustache.5.html ****************************************************/ @@ -13,39 +11,42 @@ void setup() { Serial.begin(115200); Serial.println(""); - // Create a JSON object to hold the data that we'll use in our template. It looks like this: - // { - // "Alice": { - // "name": "Alice", - // "role": "Engineer" - // }, - // "Bob": { - // "name": "Bob", - // "role": "Intern" - // } - // } + // Create a JsonDocument instance to hold the data that we'll use in our template + const char* json = R"""( + { + "people": [ + { + "name": "Alice", + "role": "Engineer" + }, + { + "name": "Bob", + "role": "Intern" + } + ] + } + )"""; JsonDocument data; - auto people = data["people"].to(); - auto alice = people.add(); - alice["name"] = "Alice"; - alice["role"] = "Engineer"; - auto bob = people.add(); - bob["name"] = "Bob"; - bob["role"] = "Intern"; - - // Create a template string that renders the data for a single person. This is a partial. + deserializeJson(data, json); + + // Create a template string that renders the data for a single person. This is a *partial*. String personString = "Name: {{name}}\tRole: {{role}}\n"; // Create a template string that renders the data for all people. This is the main template. + // Note that it loops over a field called "people" and includes the partial "person" for each of + // them. String reportString = "People report:\n{{#people}}{{> person}}{{/people}}"; // Render the template with the data. The third argument is the partials list. This - // defines how to map a partial reference like {{>person }} to a particular template - // (personString). + // defines how to map a partial reference like "person" to a particular template + // ("personString"). String output = ministache::render(reportString, data, {{"person", personString}}); // Print the result Serial.println(output); + + // Expected output: + // // People report: // Name: Alice Role: Engineer // Name: Bob Role: Intern diff --git a/library.json b/library.json new file mode 100644 index 0000000..b9d2912 --- /dev/null +++ b/library.json @@ -0,0 +1,39 @@ +{ + "name": "Ministache", + "version": "1.0.0", + "description": "Ministache is a small, fast and spec-complete implementation of the Mustache templating language for Arduino. All core Mustache tags are supported: interpolation, partials, sections, inverted sections, custom delimiters, and comments.", + "keywords": ["mustache", "moustache", "text", "text processor", "template", "logic-less", "html"], + "repository": { + "type": "git", + "url": "https://github.com/floatplane/ministache" + }, + "authors": [ + { + "name": "Brian Sharon", + "url": "https://github.com/floatplane", + "maintainer": true + } + ], + "license": "MIT", + "platforms": "*", + "headers": "Ministache.h", + "examples": [ + { + "name": "Basic", + "base": "examples/basic", + "files": ["basic.ino"] + }, + { + "name": "Partials", + "base": "examples/partials", + "files": ["partials.ino"] + } + ], + "dependencies": { + "bblanchon/ArduinoJson": "^7.0.0" + }, + "build": { + "unflags": "-std=gnu++11", + "flags": "-std=gnu++17" + } +} \ No newline at end of file diff --git a/library.properties b/library.properties index 97b36ce..cda687d 100644 --- a/library.properties +++ b/library.properties @@ -3,7 +3,7 @@ version=1.0.0 author=Brian Sharon maintainer=Brian Sharon sentence=Implementation of the Mustache templating language for Arduino -paragraph=Ministache is a small, fast and complete implementation of the Mustache templating language for Arduino. +paragraph=Ministache is a small, fast and spec-complete implementation of the Mustache templating language for Arduino. category=Data Processing url=https://github.com/floatplane/ministache architectures=*