Skip to content

Commit

Permalink
Updated README
Browse files Browse the repository at this point in the history
Updated composer.json

Updated Symfony mb polyfill to 1.2.0

Addressed #100, still not satisfied with the solution (but it works well, for ternary operators at least)

Addressed #109, the ignored variables are now a constant Tale\Jade\Compiler\IGNORED_SCOPE_VARIABLES. Define it prior to loading Tale Jade to specify own ignored variables (separated by `:`)
  • Loading branch information
Torben Köhn committed Aug 23, 2016
1 parent 4134b0a commit 727a7b5
Show file tree
Hide file tree
Showing 7 changed files with 131 additions and 50 deletions.
34 changes: 11 additions & 23 deletions Compiler.php
Original file line number Diff line number Diff line change
Expand Up @@ -336,12 +336,6 @@ public function __construct(array $options = null, Parser $parser = null, Lexer
'echo_xml_doctype' => defined('HHVM_VERSION'),
'paths' => [],
'extensions' => ['.jd', '.jade'],
'ignored_scope_variables' => [
'GLOBALS', '_SERVER', '_GET', '_POST',
'_FILES', '_REQUEST', '_SESSION', '_ENV', '_COOKIE',
'php_errormsg', 'HTTP_RAW_POST_DATA', 'http_response_header',
'argc', 'argv', '__scope', '__arguments', '__ignore', '__block'
],
'parser_options' => [],
'lexer_options' => []
], $options);
Expand Down Expand Up @@ -1473,16 +1467,14 @@ protected function compileMixinCall(Node $node)
}

$phtml .= (count($node->children) > 0 ? $this->indent() : '').$this->createCode(
'$__ignore = array_flip('.$this->exportArray($this->options['ignored_scope_variables']).');
$__scope = array_diff_key(array_replace(get_defined_vars(), $__ignore), $__ignore);
$__mixinCallArgs = '.$this->exportArray($args).';'.($hasBlock ? '
$__mixinCallArgs[\'__block\'] = isset($__block) ? $__block : null;
' : '').'
call_user_func($__mixins[\''.$name.'\'], $__mixinCallArgs, $__scope);
unset($__ignore);
unset($__scope);
unset($__mixinCallArgs);
'.($hasBlock ? 'unset($__block);' : '')
'$__scope = \\Tale\\Jade\\Compiler\\create_scope(get_defined_vars()); '.
'$__mixinCallArgs = '.$this->exportArray($args).';'.(
$hasBlock ? '$__mixinCallArgs[\'__block\'] = isset($__block) ? $__block : null; ' : ''
).'call_user_func($__mixins[\''.$name.'\'], $__mixinCallArgs, $__scope); '.
'unset($__scope); '.
'unset($__mixinCallArgs); '.(
$hasBlock ? 'unset($__block); ' : ''
)
).$this->newLine();

return $phtml;
Expand All @@ -1505,13 +1497,9 @@ protected function compileBlock(Node $node)

if (!$name)
return $this->createCode(
'$__ignore = array_flip('.$this->exportArray($this->options['ignored_scope_variables']).');
$__scope = array_diff_key(array_replace(get_defined_vars(), $__ignore), $__ignore);
echo isset($__block) && $__block instanceof \Closure ? $__block($__scope) : \'\';
unset($__ignore);
unset($__scope);'
'$__scope = \\Tale\\Jade\\Compiler\\create_scope(get_defined_vars()); '.
'echo isset($__block) && $__block instanceof \Closure ? $__block($__scope) : \'\'; '.
'unset($__scope);'
);

//At this point the code knows this block only, since handleBlock took care of the blocks previously
Expand Down
41 changes: 33 additions & 8 deletions Compiler/functions.php
Original file line number Diff line number Diff line change
Expand Up @@ -219,29 +219,54 @@ function flatten(array $array, $separator = ' ', $argSeparator = '=')
}
}

if (!function_exists(__NAMESPACE__.'\\get_or_set_ignored_scope_variables')) {
if (!defined(__NAMESPACE__.'\\IGNORED_SCOPE_VARIABLES')) {

define(
__NAMESPACE__.'\\IGNORED_SCOPE_VARIABLES',
'GLOBALS:_SERVER:_GET:_POST:_FILES:_REQUEST:_SESSION:_ENV:_COOKIE:php_errormsg:'.
'HTTP_RAW_POST_DATA:http_response_header:argc:argv:__scope:__arguments:__ignore:__block'
);
}

if (!function_exists(__NAMESPACE__.'\\get_ignored_scope_variables')) {

/**
* Stores the currently ignored scope variables.
* Returns the variable names to ignore when handling scoping for mixins.
*
* This is only a way to make them configurable and not require to copy them all over
* the jade code.
*
* This is needed to preserve the stand-alone mode.
*
* @param array $variableNames the variable names to ignore in the jade code when scoping (set)
* @return string the variable names to ignore in the jade code when scoping (get)
* @return array the variable names to ignore in the jade code when scoping
*
*/
function get_or_set_ignored_scope_variables(array $variableNames = null)
function get_ignored_scope_variables()
{

static $ignoredScopeVariables = [];
static $ignoredScopeVariables = null;

if ($variableNames)
$ignoredScopeVariables = $variableNames;
if (!$ignoredScopeVariables)
$ignoredScopeVariables = explode(':', __NAMESPACE__.'\\IGNORED_SCOPE_VARIABLES');

return $ignoredScopeVariables;
}
}

if (!function_exists(__NAMESPACE__.'\\create_scope')) {

/**
* This will return a diff of currently defined variables and variables to ignore.
*
* The passed argument usually should be the result of `get_defined_variables()`
*
* @return array the final scope variables and values
*/
function create_scope(array $definedVariables)
{

$ignore = get_ignored_scope_variables();
return array_diff_key(array_replace($definedVariables, $ignore), $ignore);
}
}
}
26 changes: 25 additions & 1 deletion Lexer.php
Original file line number Diff line number Diff line change
Expand Up @@ -1762,8 +1762,32 @@ protected function scanAttributes()
? $token['value'].$value
: $value;
$spaces = null;
}

//If this is a ternary operator, there might be more?
//Try to fetch ternaries without surrounding brackets
if ($this->match('\s*\?')) {

$token['value'] .= $this->getMatch(0);
$this->consumeMatch();
$token['value'] .= $this->read('ctype_space');

//Get the middle (if) value
$token['value'] .= $this->readBracketContents($argSeparators);

if (!$this->match('\s*:'))
$this->throwException(
'Invalid ternary operator defined. You\'re missing the double colon to specify an else-block'
);

$token['value'] .= $this->getMatch(0);
$this->consumeMatch();
$token['value'] .= $this->read('ctype_space');

//Get the last (else) value
$token['value'] .= $this->readBracketContents($argSeparators);
}
}

yield $token;

if (!empty($spaces)) {
Expand Down
52 changes: 43 additions & 9 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,44 @@ The Tale Jade Template Engine brings the popular and powerful Templating-Languag

Tale Jade is the first complete and most powerful Jade implementation in PHP.


**Contents:**

- [What is Tale Jade](#what-is-tale-jade)
- [Getting Started / Installation](#getting-started)
- [Supported Features](#supported-features)
- [Documentation Resources](#documentation-resources)
- [Tale Jade in your favorite framework](#tale-jade-in-your-favorite-framework)
- [Get in touch & support my work](#get-in-touch-and-support-my-work)



**Currently looking for contributors because of lacking time. This will not cease development on my side, I just need one or two helping hands. If you're interested, drop an E-Mail on [torben@talesoft.codes](mailto:torben@talesoft.codes). Thank you.**

---


## What is Tale Jade

It's a template engine that doesn't focus on abstracting PHP, but focuses on abstracting **HTML**.

**Why another template engine, you might ask?**

Template engines like Twig or Blade are pretty cool and functional, but they all lack one common thing: **HTML abstraction**.

You still have to write all those tags, brackets and quotes, you have to close tags and make sure that you keep your structure consistent. It's verbose and it tages large sizes on large sites pretty quick.

Similar to HAML, but less verbose, Tale Jade takes both approaches, it abstracts PHP as well as HTML. It works based on indentation and simple CSS-selectors to create your HTML as clean and quick as possible. It also involves a lot of dynamic features, you won't need any line of HTML or PHP to write your templates anymore. _You only need Tale Jade_.

Furthermore, Tale Jade can handle different output formats through its syntax. That way you can use Tale Jade for HTML5, XHTML or XML templates just by changing the doctype and it will automatically make sure to always render valid markup.

Below you have some examples, feature-links, links to documentation and a sandbox where you can play in. Check them out!

Don't fear the syntax. Let me stress this out because I've read a lot about people _being scared_ of Jade syntax.
It is basically indented CSS-selectors and a few characters to control what you output.
Once you wrote a few templates with it, I assure you, **you'll love it**!


## Getting Started


Expand All @@ -30,15 +64,14 @@ If you want to get started right now, hook up [composer](https://getcomposer.org

```bash
$ composer require "talesoft/tale-jade:*"
$ composer install
```

or add it to your `composer.json` by yourself

```json
{
"require": {
"talesoft/tale-jade": "*"
"talesoft/tale-jade": "^1.4.5"
}
}
```
Expand Down Expand Up @@ -171,7 +204,7 @@ This always has been and will always be the main target.
PHP has it's own features that are surely different from JavaScript's.
By utilizing those features it aims to bring in more, compatible features into the language to make the fastest template development ever possible!

**You can try features and see a bunch of examples on my [sandbox site](http://sandbox.jade.talesoft.codes)**
**You can try each feature and see a bunch of examples on my [sandbox site](http://sandbox.jade.talesoft.codes)**

### Supported official Node.js Jade Features

Expand Down Expand Up @@ -308,16 +341,17 @@ A great thanks to the contributors of these modules!
---


## Get in touch
## Get in touch and support my work

If you find a bug or miss a function, please use the [Issues](https://github.com/Talesoft/tale-jade/issues) on this page to tell me about it. I will gladly hear you out :)

If you find a bug or miss a function, please use the [Issues](https://github.com/Talesoft/tale-jade/issues) on this page
to tell me about it. I will gladly hear you out :)

Don't forget to [support my work](https://www.paypal.me/TorbenKoehn) if you like it!
If this library helped you, eased up your work and you simply can't live without it, think about supporting my work and [spend me a coffee](https://www.paypal.me/TorbenKoehn). Thank you!


If you'd like to contribute, fork, send pull requests and I'll take a deep look at what you've been working at!
Tale Jade is completely **Open Source**! You can do anything you like with the code as long as you stick to the
**MIT-license** we've appended. Just keep my name somewhere around!
Tale Jade is completely **Open Source**! You can do anything you like with the code as long as you stick to the **MIT-license** I've appended. Just keep my name somewhere around!


You can also contact me via E-Mail [torben@talesoft.codes](mailto:torben@talesoft.codes)

Expand Down
10 changes: 10 additions & 0 deletions Test/AttributeTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,16 @@ public function testUnnamedAttributed()

$this->setExpectedException(Compiler\Exception::class);
$this->assertEquals('', $this->renderer->compile('a(="some value")'));

$this->setExpectedException(Compiler\Exception::class);
$this->assertEquals('', $this->renderer->compile('a("some value")'));
}

public function testTernaryExpressionValue()
{

$this->assertEquals('<a<?php $__value = true ? \'some value\' : false; if (!\Tale\Jade\Compiler\is_null_or_false($__value)) echo \' some-attr=\'.\Tale\Jade\Compiler\build_value($__value, \'"\', true); unset($__value);?>></a>', $this->renderer->compile('a(some-attr=true ? \'some value\' : false)'));
$this->assertEquals('<a<?php $__value = true ? \'some value\' : false; if (!\Tale\Jade\Compiler\is_null_or_false($__value)) echo \' some-attr=\'.\Tale\Jade\Compiler\build_value($__value, \'"\', true); unset($__value);?> title="test"></a>', $this->renderer->compile('a(some-attr=true ? \'some value\' : false title="test")'));
}

public function testExpectedButNotGivenValue()
Expand Down
2 changes: 1 addition & 1 deletion composer.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "talesoft/tale-jade",
"type": "library",
"keywords": ["template", "dialect", "html", "views", "presentation", "jade", "html", "php", "phtml"],
"keywords": ["template", "dialect", "html", "views", "render", "presentation", "jade", "html", "php", "phtml"],
"description": "A clean, lightweight and easy-to-use templating engine for PHP based on Jade/Pug",
"license": "MIT",
"homepage": "http://jade.talesoft.codes",
Expand Down
16 changes: 8 additions & 8 deletions composer.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit 727a7b5

Please sign in to comment.