Skip to content

Commit

Permalink
Merge branch 'master' into inclusion
Browse files Browse the repository at this point in the history
  • Loading branch information
blambeau committed Jan 13, 2011
2 parents d2861c7 + cec06e9 commit aefb7fe
Show file tree
Hide file tree
Showing 7 changed files with 296 additions and 249 deletions.
1 change: 1 addition & 0 deletions .gitignore
@@ -1,2 +1,3 @@
pkg
doc/api
.yardoc
79 changes: 79 additions & 0 deletions CHANGELOG.md
@@ -0,0 +1,79 @@
# Version 0.9.3

## Development-based changesets

* Moved to rspec 2.4.0
* Moved from rdoc to yard for generating the documentation
* README, CHANGELOG and LICENCE are now in Mardown instead of rdoc

# Version 0.9.2

## New features (by order of importance)

* Implements main transformer on dialects
* Makes coderay encoders available without options using a bit of meta programming
* System-local absolute paths (i.e. starting with '/') are recognized by buffer rulesets

# Version 0.9.1

## Bug fixes

* #307, about HashScope.has_key? which returned nil instead of false in some situations

## Broken features and APIs (by order of importance)

* HostedLanguage::DSL is strictly private and should be reopened. Methods added to this class
will never be available in templates. Use HostedLanguage.variable_missing instead.
* ::WLang::BasicObject has been removed. HostedLanguage::DSL implements its own strategy, which
is spec tested in test/spec/basic_object.spec

## New features (by order of importance)

* WLang does not requires the rdoc gem by default
* A new encoder redcloth/xhtml allows using Textile markups easily
* The wlang/xhtml dialect provides a tag helper for links @{...}{...}
* The parser class returns friendly messages when a rule is ill-implemented

# Version 0.9.0

## Broken features and APIs (by order of importance)

* Major broken API in WLang.instantiate and WLang.file_instantiate which do not allow passing
buffers anymore
* Hash are not methodized by default anymore (major broken feature with 0.8.x versions)
* Expressions 'a la' PHP w@w (sections/.../.../id) are not supported anymore
* The default hosted language raises a WLang::UndefinedVariableError when a variable cannot be
found in the current template scope (0.8.x versions returned nil in this case)
* Template.initialize does not take a default context anymore
* WLang::Parser.context_xxx do not exist anymore. Use branch(...) instead
* WLang::Parser::Context removed, and WLang::HashScope introduced
* WLang::Parser instance variables are all made protected

## New features (by order of importance)

* WLang::HostingLanguage introduced, with a default one for Ruby. The hosting language
is the way to provide a main scope, accessible to all templates at once.
* WLang::HostingLanguage is not sensitive to the difference between symbol keys and strings
* Buffering and Context rulesets now branch the current parser instead of creating a new one
* WLang::Error and subclasses propose a backtrace information
* WLang::Parser refactored to encapsulate the whole state in another class (WLang::Parser::State)
* WLang facade has been made much more robust as it now checks all its arguments.
* WLang::dialect may now be used to ensure dialect instances from both Dialect args and qualified names.
* Introduction of WLang.template and WLang.file_template
* plain-text dialect proposes new camel-based encoders
* wlang/active-string dialect has the imperative rule set included
* sql dialect has been added
* ruby dialect proposes a method-case encoder

# Version 0.8.5

* Enhances error messages a lot
* Some bug fixes for ruby 0.8.7

# Version 0.8.4

* Migration from svn.chefbe.net to github.com

# Version 0.8.0

* First public version
73 changes: 0 additions & 73 deletions CHANGELOG.rdoc

This file was deleted.

2 changes: 1 addition & 1 deletion LICENCE.rdoc → LICENCE.md
@@ -1,4 +1,4 @@
= Licence
# Licence

The MIT License

Expand Down
174 changes: 174 additions & 0 deletions README.md
@@ -0,0 +1,174 @@
# What is _wlang_ ?

_wlang_ is a simple, powerful, robust and secure <b>code generation</b>/<b>templating engine</b>
(at least, authors hope so ;-) Motivation for it can be found at http://www.revision-zero.org/wlang.
It's main aim is to help you creating web pages, sql queries, ruby code (that is, generating code in
general) without having to worry too much about html entities encoding, sql back quoting, string
escaping and the like. WLang proposes a generic engine that you can extend to fit your needs. It also
proposes standard instantiations of this engine for common tasks such as creating SQL queries,
instantiating web pages, etc.

## A collection of typical encoders

The first basic usage of WLang is to provide a collection of text encoders:

WLang::encode('&', 'xhtml/entities-encoding') # &amp;
WLang::encode("O'Neil", 'sql/single-quoting') # O\'Neil
WLang::encode("O'Neil", 'sql/sybase/single-quoting') # O''Neil
...
WLang::encode("hello world", 'plain-text/camel') # HelloWorld
WLang::encode("hello world", 'plain-text/lower-camel') # helloWorld
...
WLang::encode("helloWorld", 'ruby/method-case') # hello_world

## A powerful alternative to ruby string interpolation

The second usage is to have shortcuts for using these encoders in typical
situations:

# Hello world!
"Hello ${who}!".wlang(:who => 'world')

# Hello cruel &amp; world!
"Hello ${who}!".wlang({:who => 'cruel & world'}, 'wlang/xhtml')

# Hello blambeau, llambeau
"Hello *{authors as a}{${a}}{, }".wlang(:authors => ['blambeau', 'llambeau'])

# INSERT INTO people VALUES ('O\'Neil')
INSERT INTO people VALUES ('{who}')".wlang(:who => "O'Neil")

## A powerful templating engine

But the main usage of _wlang_ is as follows (for bold words, see terminology later):
you have a *template* file (written in a given _wlang_ *dialect*), you have some
instantiation *context* (data provided through a Ruby Hash or a yaml file for
example) and you would like to instantiate the template with that data.

Example: a template.whtml as follows
<html>
<head>
<title>${title}</title>
</head>
<body>
<h1>Hello ${who} !</h1>
</body>
</html>

Instantiation data is a hash containing values for _title_ and _who_. Instantiating
the template is straightforward:

require 'wlang'
context = {"title" => "Hello world in WLang", "who" => "Alice"}
STDOUT << WLang.file_instantiate("template.whtml", context)

## Behind the scene

- WLang helps you avoiding SQL injection and XSS attacks through the same tags reacting differently
in different contexts.
- WLang understands your context (and its dialect) from the template file extension
- WLang provides a rich collection of pre-defined tags and dialects
- WLang allows you to create your own encoders, tags and dialects while reusing existing ones
- WLang may change the current dialect during the template instantiation itself (generating
html with embedded javascript is easy and natural)
- WLang is able to generate wlang code without any perturabation

## Additional examples (availability of the tags may depend on the dialect)

* Include text files on the fly

<<{my_file.html}

* Instantiate sub-templates on the fly, passing data as arguments

<<+{my_sub_template.whtml using who: 'wlang'}

* Load data from yaml or ruby files on the fly

<<={resources.yaml as resources}{
*{resources as r}{ ${r} }
}

* WLang instrospection (basic example)

context = {:varname => 'who', :who => 'wlang'}
"Hello ${${varname}}!".wlang(context) # => Hello wlang!

* Generate a wlang template and instantiate it after that

dialect = 'wlang/active-string'
tpl = "Hello $(${varname})!" # => Hello $(${varname})
tpl = tpl.wlang(:varname => 'who') # => Hello $(who)!
tpl = tpl.wlang({:who => 'wlang'}, dialect, :parentheses) # => Hello wlang!

## Roadmap

- For terminology and a quick overview of _wlang_ for generating code, read on.
- For the current cheatsheet/specification see the file doc/specification/specification.html
- If you want to learn _wlang_ quickly, see the example directory or read examples
in the specification file (if you understand all examples in the specification file, then you
probably master wlang.
- If you want a killer example (but simple) see the way the specification.html file
is generated in doc/specification directory
- If you want to know which dialects are available (that is, in which target languages
you can generate code), see the specification as well or read the file
lib/wlang/dialects/standard_dialects.rb in the source distribution.
- If you want to create your own wlang dialect, see WLang::Dialect::DSL
- If you think that your own dialect is of generic purpose and well-designed, if
you have any question or want to contribute join us on {github}[http://github.com/blambeau/wlang].

## Terminology

_wlang_ comes with a well-defined terminology for the underlying abstractions. As
the documentation uses it, you'll probably be happy to learn about the main abstractions
and associated terms.

_template_ : Source code respecting the wlang grammar, and attached to a given <em>wlang
dialect</em>. Asbtraction implemented by WLang::Template.

_dialect_ : Basically, <em>dialect</em> is used as a synonym for (programming) <em>language</em>.
However _wlang_ uses a tree of dialects, allowing specializations: <tt>sql/sybase</tt>
for example is the qualified name of a sub-dialect 'sybase' of the 'sql' dialect.
Dialects come with associated _encoders_. Abstraction implemented by WLang::Dialect.

_wlang dialect_ : When we talk about a <em>wlang dialect</em>, we are actually refering to some
specialization of the wlang tag-based grammar: <tt>wlang/xhtml</tt> for example
is the templating language _wlang_ proposes to generate xhtml pages. An
example of source code in that dialect has been shown before.
In addition to its encoders a <em>wlang dialect</em> comes with its sets of _tags_
and associated _rules_. Abstraction implemented by WLang::Dialect as well as
WLang::EncoderSet and WLang::RuleSet.

_encoder set_ : Reusable set of <em>encoders</em>, attached to a dialect. Abstraction
implemented by WLang::EncoderSet.

_encoder_ : Text transformation (algorithm) applying some encoding conventions of a portion
of a the target language generated by a dialect. HTML entities-encoding, SQL's back-quoting
are examples of encoders. Encoders are accessible through their qualified name:
xhtml/entities-encoding and sql/back-quoting in the examples. Abstraction implemented by
WLang::Encoder.

_ruleset_ : Reusable set of <em>tags</em> associated to <em>rule</em>s. Abstraction
implemented by WLang::RuleSet.

_wlang tag_ : Special tags in the template, starting with wlang symbols and a number of wlang
blocks. A tag is associated with a wlang rule. Examples: <tt>${...}</tt> is a
tag with only one block, while <tt>?{...}{...}{...}</tt> is another tag but with
three blocks.

_rule_ : Transformation semantics of a given <em>tag</em>. When wlang instantiates a
template it simply replaces <em>wlang tags</em> by some <em>replacement value</em>
(which is always a string). This value is computed by the rule attached to
the tag. Rule definition explicitly describes the number of blocks it expects, in which dialect they
are parsed and instantiated and the way the replacement value is computed.
Example: <tt>^{wlang/active-string}{...}</tt> (also known as 'encoding')
instantiates #1, looking for an encoder qualified name. Instantiates #2 in
the current dialect. Encode #2's instantiation using encoder found in (#1)

_context_ : Some rules allow code to be executed in the <em>hosting language</em> (the
definition explicitly announce it by putting <tt>wlang/hosted</tt> in the corresponding
block). When doing so, this code is in fact executed in a given context that
provides the execution semantics. Abstraction implemented in WLang::Parser::Context.

_hosting language_ : language (or framework) that executes wlang. In this case, it will be
<tt>ruby</tt>.

0 comments on commit aefb7fe

Please sign in to comment.