Add 'packages/mustache/' from commit 'd0335a925d7199f3a5988ca10da36fee38ce0c43'
git-subtree-dir: packages/mustache git-subtree-mainline:9458a72c57
git-subtree-split:d0335a925d
This commit is contained in:
commit
c94bec26ec
17 changed files with 281 additions and 0 deletions
30
packages/mustache/.gitignore
vendored
Normal file
30
packages/mustache/.gitignore
vendored
Normal 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
|
1
packages/mustache/.travis.yml
Normal file
1
packages/mustache/.travis.yml
Normal file
|
@ -0,0 +1 @@
|
||||||
|
language: dart
|
2
packages/mustache/CHANGELOG.md
Normal file
2
packages/mustache/CHANGELOG.md
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
# 2.0.0
|
||||||
|
* Angel 2 and Dart 2 support.
|
21
packages/mustache/LICENSE
Normal file
21
packages/mustache/LICENSE
Normal 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.
|
35
packages/mustache/README.md
Normal file
35
packages/mustache/README.md
Normal 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`.
|
2
packages/mustache/analysis_options.yaml
Normal file
2
packages/mustache/analysis_options.yaml
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
analyzer:
|
||||||
|
strong-mode: true
|
16
packages/mustache/example/main.dart
Normal file
16
packages/mustache/example/main.dart
Normal 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'});
|
||||||
|
});
|
||||||
|
}
|
32
packages/mustache/lib/angel_mustache.dart
Normal file
32
packages/mustache/lib/angel_mustache.dart
Normal 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);
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
59
packages/mustache/lib/src/cache.dart
Normal file
59
packages/mustache/lib/src/cache.dart
Normal 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);
|
||||||
|
}
|
||||||
|
}
|
20
packages/mustache/lib/src/mustache_context.dart
Normal file
20
packages/mustache/lib/src/mustache_context.dart
Normal 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}');
|
||||||
|
}
|
||||||
|
}
|
14
packages/mustache/mustache.iml
Normal file
14
packages/mustache/mustache.iml
Normal 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>
|
15
packages/mustache/pubspec.yaml
Normal file
15
packages/mustache/pubspec.yaml
Normal 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:
|
30
packages/mustache/test/all_test.dart
Normal file
30
packages/mustache/test/all_test.dart
Normal 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!"));
|
||||||
|
});
|
||||||
|
}
|
1
packages/mustache/test/foo/bar.mustache
Normal file
1
packages/mustache/test/foo/bar.mustache
Normal file
|
@ -0,0 +1 @@
|
||||||
|
{{framework}}_framework
|
1
packages/mustache/test/hello.mustache
Normal file
1
packages/mustache/test/hello.mustache
Normal file
|
@ -0,0 +1 @@
|
||||||
|
Hello, {{name}}!
|
1
packages/mustache/test/partials/name.mustache
Normal file
1
packages/mustache/test/partials/name.mustache
Normal file
|
@ -0,0 +1 @@
|
||||||
|
world
|
1
packages/mustache/test/with-partial.mustache
Normal file
1
packages/mustache/test/with-partial.mustache
Normal file
|
@ -0,0 +1 @@
|
||||||
|
Hello, {{> name}}!
|
Loading…
Reference in a new issue