Add 'packages/mustache/' from commit 'd0335a925d7199f3a5988ca10da36fee38ce0c43'

git-subtree-dir: packages/mustache
git-subtree-mainline: 9458a72c57
git-subtree-split: d0335a925d
This commit is contained in:
Tobe O 2020-02-15 18:29:03 -05:00
commit c94bec26ec
17 changed files with 281 additions and 0 deletions

30
packages/mustache/.gitignore vendored Normal file
View file

@ -0,0 +1,30 @@
# See https://www.dartlang.org/tools/private-files.html
# Files and directories created by pub
.buildlog
.packages
.project
.pub/
build/
**/packages/
# Files created by dart2js
# (Most Dart developers will use pub build to compile Dart, use/modify these
# rules if you intend to use dart2js directly
# Convention is to use extension '.dart.js' for Dart compiled to Javascript to
# differentiate from explicit Javascript files)
*.dart.js
*.part.js
*.js.deps
*.js.map
*.info.json
# Directory created by dartdoc
doc/api/
# Don't commit pubspec lock file
# (Library packages only! Remove pattern if developing an application package)
pubspec.lock
.idea
.dart_tool

View file

@ -0,0 +1 @@
language: dart

View file

@ -0,0 +1,2 @@
# 2.0.0
* Angel 2 and Dart 2 support.

21
packages/mustache/LICENSE Normal file
View file

@ -0,0 +1,21 @@
The MIT License (MIT)
Copyright (c) 2016 angel-dart
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

View file

@ -0,0 +1,35 @@
# mustache
[![Gitter](https://img.shields.io/gitter/room/nwjs/nw.js.svg)](https://gitter.im/angel_dart/discussion)
[![version](https://img.shields.io/pub/v/angel_mustache.svg)](https://pub.dartlang.org/packages/angel_mustache)
[![build status](https://travis-ci.org/angel-dart/mustache.svg?branch=master)](https://travis-ci.org/angel-dart/mustache)
Mustache (Handlebars) view generator for the [Angel](https://github.com/angel-dart/angel)
web server framework.
Thanks so much @c4wrd for his help with bringing this project to life!
# Installation
In `pubspec.yaml`:
```yaml
dependencies:
angel_mustache: ^2.0.0
```
# Usage
```dart
const FileSystem fs = const LocalFileSystem();
configureServer(Angel app) async {
// Run the plug-in
await app.configure(mustache(fs.directory('views')));
// Render `hello.mustache`
await res.render('hello', {'name': 'world'});
}
```
# Options
- **partialsPath**: A path within the viewsDirectory to search for partials in.
Default is `./partials`.
- **fileExtension**: The file extension to search for. Default is `.mustache`.

View file

@ -0,0 +1,2 @@
analyzer:
strong-mode: true

View file

@ -0,0 +1,16 @@
import 'package:angel_framework/angel_framework.dart';
import 'package:angel_mustache/angel_mustache.dart';
import 'package:file/file.dart';
import 'package:file/local.dart';
const FileSystem fs = const LocalFileSystem();
configureServer(Angel app) async {
// Run the plug-in
await app.configure(mustache(fs.directory('views')));
// Render `hello.mustache`
app.get('/', (req, res) async {
await res.render('hello', {'name': 'world'});
});
}

View file

@ -0,0 +1,32 @@
library angel_mustache;
import 'package:angel_framework/angel_framework.dart';
import 'package:file/file.dart';
import 'package:mustache4dart/mustache4dart.dart' show render;
import 'package:path/path.dart' as p;
import 'src/cache.dart';
import 'src/mustache_context.dart';
mustache(Directory viewsDirectory,
{String fileExtension: '.mustache', String partialsPath: './partials'}) {
Directory partialsDirectory = viewsDirectory.fileSystem
.directory(p.join(p.fromUri(viewsDirectory.uri), partialsPath));
MustacheContext context =
new MustacheContext(viewsDirectory, partialsDirectory, fileExtension);
MustacheViewCache cache = new MustacheViewCache(context);
return (Angel app) async {
app.viewGenerator = (String name, [Map data]) async {
var partialsProvider;
partialsProvider = (String name) {
String template = cache.getPartialSync(name, app);
return render(template, data ?? {}, partial: partialsProvider);
};
String viewTemplate = await cache.getView(name, app);
return await render(viewTemplate, data ?? {}, partial: partialsProvider);
};
};
}

View file

@ -0,0 +1,59 @@
import 'dart:async';
import 'dart:collection';
import 'package:file/file.dart';
import 'package:angel_framework/angel_framework.dart';
import 'package:angel_mustache/src/mustache_context.dart';
class MustacheViewCache {
/**
* The context for which views and partials are
* served from.
*/
MustacheContext context;
HashMap<String, String> viewCache = new HashMap();
HashMap<String, String> partialCache = new HashMap();
MustacheViewCache([this.context]);
Future<String> getView(String viewName, Angel app) async {
if (app.isProduction) {
if (viewCache.containsKey(viewName)) {
return viewCache[viewName];
}
}
File viewFile = context.resolveView(viewName);
if (viewFile.existsSync()) {
String viewTemplate = await viewFile.readAsString();
if (app.isProduction) {
this.viewCache[viewName] = viewTemplate;
}
return viewTemplate;
} else
throw new FileSystemException(
'View "$viewName" was not found.', viewFile.path);
}
String getPartialSync(String partialName, Angel app) {
if (app.isProduction) {
if (partialCache.containsKey(partialName)) {
return partialCache[partialName];
}
}
File partialFile = context.resolvePartial(partialName);
if (partialFile.existsSync()) {
String partialTemplate = partialFile.readAsStringSync();
if (app.isProduction) {
this.partialCache[partialName] = partialTemplate;
}
return partialTemplate;
} else
throw new FileSystemException(
'View "$partialName" was not found.', partialFile.path);
}
}

View file

@ -0,0 +1,20 @@
import 'package:file/file.dart';
import 'package:path/path.dart' as path;
class MustacheContext {
Directory viewDirectory;
Directory partialDirectory;
String extension;
MustacheContext([this.viewDirectory, this.partialDirectory, this.extension]);
File resolveView(String viewName) {
return viewDirectory.childFile('${viewName}${extension}');
}
File resolvePartial(String partialName) {
return partialDirectory.childFile('${partialName}${extension}');
}
}

View file

@ -0,0 +1,14 @@
<?xml version="1.0" encoding="UTF-8"?>
<module type="WEB_MODULE" version="4">
<component name="NewModuleRootManager" inherit-compiler-output="true">
<exclude-output />
<content url="file://$MODULE_DIR$">
<excludeFolder url="file://$MODULE_DIR$/.pub" />
<excludeFolder url="file://$MODULE_DIR$/build" />
</content>
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
<orderEntry type="library" name="Dart SDK" level="project" />
<orderEntry type="library" name="Dart Packages" level="project" />
</component>
</module>

View file

@ -0,0 +1,15 @@
name: angel_mustache
description: Mustache view generator for Angel.
author: thosakwe <thosakwe@gmail.com>
homepage: https://github.com/angel-dart/angel_mustache
version: 2.0.0
environment:
sdk: ">=2.0.0-dev <3.0.0"
dependencies:
angel_framework: ^2.0.0-alpha
file: ^5.0.0
mustache4dart: ^3.0.0-dev
path: ^1.0.0
dev_dependencies:
http:
test:

View file

@ -0,0 +1,30 @@
import 'dart:async';
import 'package:angel_framework/angel_framework.dart';
import 'package:angel_mustache/angel_mustache.dart';
import 'package:file/local.dart';
import 'package:test/test.dart';
main() async {
Angel angel = new Angel();
await angel.configure(mustache(const LocalFileSystem().directory('./test')));
test('can render templates', () async {
var hello = await angel.viewGenerator('hello', {'name': 'world'});
var bar = await angel.viewGenerator('foo/bar', {'framework': 'angel'});
expect(hello, equals("Hello, world!"));
expect(bar, equals("angel_framework"));
});
test('throws if view is not found', () {
expect(new Future(() async {
var fails = await angel.viewGenerator('fail', {'this_should': 'fail'});
print(fails);
}), throws);
});
test("partials", () async {
var withPartial = await angel.viewGenerator('with-partial');
expect(withPartial, equals("Hello, world!"));
});
}

View file

@ -0,0 +1 @@
{{framework}}_framework

View file

@ -0,0 +1 @@
Hello, {{name}}!

View file

@ -0,0 +1 @@
world

View file

@ -0,0 +1 @@
Hello, {{> name}}!