Code Monkey home page Code Monkey logo

lightncandy's People

Contributors

brunobg avatar cjbarth avatar dixstonz3 avatar ebernhardson avatar endel avatar flashvnn avatar flip111 avatar hfhchan avatar jmgq avatar keeto avatar kfreiman avatar krinkle avatar legoktm avatar matthiasmullie avatar puritys avatar reedy avatar shahyar avatar southparkfan avatar ssnau avatar thesjg avatar yurikuzn avatar zordius avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

lightncandy's Issues

Support {{number}} is not valid in handlebars.js

MEMO: {{0}} is not valid in handlebars.js, but it can stands for first child of an array. So far lightncandy supports {{0}} , {{1}} , more. But, we may need a proper runtime / compile time flag to turn off this feature to ensure the rendering results can align with handlebars.js.

Behavior changes when data type changes

Template:

{{#items}}
    {{#value}}{{.}}{{/value}}
{{/items}}

When parameters are like the following everything is ok:

            'items' => [
                ['value'=>1],
            ],

Error is triggered when 'value' is changed to string:

            'items' => [
                ['value'=>'1'],
            ],

Text of error:

htmlentities() expects parameter 1 to be string, array given

Compiled template:

<?php return function ($in, $debugopt = 1) {
    $cx = Array(
        'flags' => Array(
            'jstrue' => false,
            'jsobj' => false,
            'spvar' => false,
            'prop' => false,
            'method' => false,
            'mustlok' => false,
            'debug' => $debugopt,
        ),
        'helpers' => Array(),
        'blockhelpers' => Array(),
        'hbhelpers' => Array(),
        'partials' => Array(),
        'scopes' => Array($in),
        'sp_vars' => Array(),

    );
    return ''.LCRun3::sec($cx, ((is_array($in) && isset($in['items'])) ? $in['items'] : null), $in, false, function($cx, $in) {return '
    '.LCRun3::sec($cx, ((is_array($in) && isset($in['value'])) ? $in['value'] : null), $in, false, function($cx, $in) {return ''.htmlentities($in, ENT_QUOTES, 'UTF-8').'';}).'
';}).'';
}
?>

Subexpressions support

Hi Zordius,

We're working on a project and we're trying to use subexpressions for handlebars.
Will subexpressions be supported in lightncandy?

Thanks!

allow_url_include = Off

Hi Zordius,
I was testing your template library and I found it great!

But I saw for using your library I need to turn on allow_url_include, not to bad but this requirement would expose all my environment to accept string inside the include(), so I decide to do a small change in the prepare().

Basic I create a temporary file and after I include it.

I need to do more testing for see the difference also in performance, I let you know if is working good.

With this I let you know I fork your repository, I hope you are happy of that.
Regards, Mauro.

Memory usage compare
Sec. execution

Edit: I don't think it is bad. Just a little price to pay for little bit of security.

helper :: Array to String conversion error

What I did:

The helper

function helper_toEuro($price){
    if(is_numeric(trim($price))){
        $price = number_format($price, 2, ',', '.');
        $price = str_replace(',00', ',-', $price);
        return "&euro; ".$price; 
     } else {
         return $price;
     }
}

The init of LightnCandy (a part of)

// Prepare compiler 
$oLightnCandySettings   = Array(
                                'flags' => LightnCandy::FLAG_STANDALONE | LightnCandy::FLAG_HANDLEBARSJS | LightnCandy::FLAG_PARENT | LightnCandy::FLAG_SPVARS,
                                'basedir' => Array($this->baseDir),
                                'fileext' => $this->utils->addHeadingValue($this->extensions, "."),
                                'helpers' => Array(
                                    "helper_toEuro",
                                    "helper_scoreToStars",
                                    "helper_uniqueId"
                                )
                            );
// compile    
$sCompiledTemplate       = LightnCandy::compile($sTemplate, $oLightnCandySettings);

And how I call the helper :

{{{helper_toEuro "8"}}}
{{{helper_toEuro F}}}

The following error is thrown:

Notice: Array to string conversion in /mnt/htdocs/inbouwWerkmap3.0/application/class/lightncandy/src/lightncandy.php on line 1357

Error when trying to use anonymous function as a helper

I'm having trouble to use an anonymous function as a helper, the compiled code is wrong

Error:
syntax error, unexpected '=>' (T_DOUBLE_ARROW), expecting ')'

$compileOptions = [
    'flags' => LightnCandy::FLAG_HANDLEBARSJS,
    'helpers' => [
        'url',
        'render' => function($view,$data = array()) {
            return View::make($view,$data);
        }
    ]
];

LightnCandy::compile(file_get_contents($view),$compileOptions);
// template:
<div class="terms-text">
{{render "artists-terms"}}
</div>
// compiled code

<?php return function ($in, $debugopt = 1) {
    $cx = Array(
        'flags' => Array(
            'jstrue' => true,
            'jsobj' => true,
            'spvar' => true,
            'debug' => $debugopt,
        ),
        'helpers' => Array(            'url' => function($path = null, $parameters = array(), $secure = null)
    {
        return app('url')->to($path, $parameters, $secure);
    },
            'render' =>                 'render' => function($view,$data = array()) {
                    return View::make($view,$data);
                }
,
)
...

It's doubling the " 'render' => " definition at the compiled code. There's something wrong with my setup, or it is really an issue?

Mistake in documentation

The inverse function closure in block helpers is called 'inv' not 'inverse' as your docs state.

Send root context value to helper or partial

I tried the following :

{{{helper_people @root.site.people}}}

This receives a string as parameter [object object]

I tried a partial (prefered)

{{@root.site.people}}
{{>reusable/partial}}
{{/@root.site.people}}

This results in a compile error

I tried a partial like this:

{{>reusable/partial @root.site.people}}

Nothing happens....

When calling the helper or the partial with an object that is not in the root context, the partial and helper renders fine.

Helpers not receiving $input arg

Hello,

Helper functions don't receive $input arg. According to specs:

When you pass arguments as name=value pairs, the input to your custom helper will > > turn into only one associative array. For example, when your custom helper is function > ($input) {...}

It's worth mentioning that if a list of arguments is passed, it works as expected.

Here's how to reproduce:

require('./lightncandy.php');

$template = '{{helper name="ernie" blah=true}}';

function myhelper() {
  print_r(func_get_args());
  exit();
}

$php = LightnCandy::compile($template, array(
  "helpers" => array(
    "helper" => "myhelper"
  )
));

$tpl = LightnCandy::prepare($php);

echo $tpl(array()); 

Output of code above:

Array
(
    [0] => 
    [1] => 
)

Many thanks for this great library!

Regards

Helper input organization

Helper

$helper = function ($input, $options=[]) {
    print_r(func_get_args());
};

Context

['test' => 'X']

Usage

{{SomeHelper test a="1" b="2"}}

Expected / Documented Input

Array
(
    [0] => X 
    [hash] => Array ( 
        [a] => 1 
        [b] => 2 
    )
 )

Current Input

Array
(
    [0] => Array
        (
            [0] => X
            [a] => 1
            [b] => 2
        )
)

Resolution?

I think that the data should not be modified, but it should be organized consistently. I prefer how the docs say, basically, populating the vars, and putting all of the html style arguments into the hash key of the options argument

Nested compilation (->compile template from helper function)

Hey there. Thank you very much for this great library.

It's fun to use and pretty flexible. However, I'm struggling to convert one aspect of my JS implementation: Compiling a new template from within a helper function.

For example, I am using a custom "partial" helper instead of using partials directly. This not only allows passing additional arguments into the partial (in case you need to overwrite some variables in the scope of the partial), it also allows responsive use of different templates.

I might call {{partial 'article'}}, but the helper will also look for 'article-phone' or 'article-tablet' depending on the screen size.

This works beautifully with handlebars.js, but does not seem to be possible with this library right now

LightnCandy::compile($template,$options);

The options array is applied every time you compile a template and there is no way around that. Since helpers are defined within the options array, I'd need access to the array while declaring it.

I hacked around this brain-melting detail by adding a new static method that applies the options array once, and removed the code from the compile() method This seemed to work at first. For reference, this is the helper I am using:

$helpers = array(
    'partial'     => function ( $name, $context ) {
        $template = file_get_contents( TPL_DIR . '/' . $name . '.html' );
        $php = LightnCandy::compile( $template );
        $renderer = LightnCandy::prepare( $php );
        echo $renderer( $context[ 'data' ][ 'root' ] );
    });

But then I noticed that the generated HTML was not "nested" as it should have been.

Consider the following structure:

/* main template */

<div id="main">
    {{partial 'body'}}
</div>
/* body partial */

<div id="body">
    {{partial 'article'}}
    This is the body
</div>
/* article partial */

<div id="article">
    I am the article
</div>

In my tests, this resulted in the following HTML:

<div id="main">
    <div id="article">
        I am the article
    </div>
    <div id="body">
        This is the body
    </div>
</div>


While it should have been

<div id="main">
    <div id="body">
        <div id="article">
            I am the article
        </div>
        This is the body
    </div>
</div>

Is there a more sane approach to achieve what I am trying to do. Is it possible at all?
Since I am heavily relying on a custom partial helper for the responsive functionality of this project, this is an absolute must have for me.

Thank you for your time (and sorry for the wall of text)

Custom helper escaping not working

Returning array($res, false) in helper callback results in output being escaped, when it should not.

Test code:

require('lightncandy.php');

$template = '{{helper}}';

function myhelper($params, $hash) {
  return array("<h1>hello</h1>", false);
}

$php = LightnCandy::compile($template, array(
  "flags" => LightnCandy::FLAG_NAMEDARG,
  "helpers" => array(
    "helper" => "myhelper"
  )
));

echo "Compiled code: $php";

$tpl = LightnCandy::prepare($php);

echo $tpl(array());

Actual Output:

&lt;h1&gt;hello&lt;/h1&gt;

Expected Output:

<h1>hello</h1>

It is worth noting that if {{{ }}} is used the result is not escaped.


Tested as of a4a680f

Helper input being filtered?

It looks like input to helpers is being filtered on the way in.

So for example, if I have a helper:

$helper = function test ($array) {
return is_array($array) ? 'T' : 'F';
}

With the template:

{{{test tmp}}}

With the context:

$context = ['tmp' => ['A', 'B', 'C']];

The value that gets sent into the helper will end up being the string A,B,C and not the array.

This seems wrong to me. I can understand filtering the data coming out, but the values going in should not be manipulated at all, they should be whatever they happened to be in the context... an array, a multidimensional array, object etc. Because the purpose of helpers is often time to take some complex data and convert it into a string format.

Makes sense?

Documentation is not clear on how to use blockhelpers

Hey there,

So, I ended up having to look in the source and figure out that you have to use the 'blockhelpers' array key to add functions to use as block helpers. I was adding them to 'helpers' and couldn't figure out why they weren't working. Could you update the documentation to reflect this?

Thanks!

Problem with length

Hi,

First of all, thank you for all your work, it's really impressive

I have a problem with length, i've got several template and the compiler doesn't seem to recognize ".length" : {{an_array.length}} (I try to find in the source but didn't find anything relative to)
Is it implemented ?
Thank you by advance

recursive partial detection

lightncandy should error and stop compile a partial when recureive partial detected and FLAG_RUNTIMEPARTIAL not used.

Custom Helper w/ alias

Running into a problem making a custom helper...

try {
    $template_compiled = LightnCandy::compile($template_html, array(
                'flags' => LightnCandy::FLAG_ERROR_EXCEPTION,
                'helpers' => array(
                    'date_format' => 'meetup_date_format'
                )
    ));
} catch (Exception $e) {
    return $e->getMessage();
}

The exception

Parse error: syntax error, unexpected 'meetup_date_format' (T_STRING), expecting '(' in C:\Windows\Temp\lci9721.tmp on line 9

Custom Helpers

I read the docs, and I understand that it is the philosophy of this project not to support custom helpers for the purpose of cross-language compatibility.

That being said, I think it should be up to the developer, so, for example, if they want to use custom helpers, they can go ahead and implement them in whatever languages they are using.

Is there any plan to add this feature in the future? I want to use this library, but I've got many custom helpers functions for my PHP Handlebars code, so that's a bit of a show stopper.

I'm looking into add into my fork:

  • support for specifying custom helpers as callbacks
  • support for compiling these calls
  • support for {{#Helper}} with no closing tag
  • support for {{#Helper with attributes}}
  • support for {{#Helper with="named attributes"}}

I am currently using the Xamin Handlebars implementation... but the lack of caching is a show stopper as I'd like to use it on high traffic sites.

Any recommendations you can give me on implementing this would be appreciated.

Great work!

runtime partial support

In #28 , we know lightncandy do not support recursive partial include.
In #62 , we know lightncandy do not support context change when include partial.

These 2 issues can be done by runtime partial logic , but need further works. Now not in plan, just memo.

Unreable value using segment-literal notation

When reading from non-valid identifiers, using something like this:

{
    "content" : {
        "@type": "value"
    }
}

I can read the value using lightncandy with:

{{content.@type}}

But not:

{{content.[@type]}}

The problem is, the first tag does not work with HandlebarsJS, the second one does.

Using the second syntax would be ideal in order to have server-side and client-side compatibility.

RAW {{{page.title}}}} results in array.

When using {{{ var }}} the compiled code shows only "array." At that point of the template.

I have objects that are used as input (typecasting for now, suggestions appreciated) but even a test with a simple array value fails.

And is there a way to a change the extension the loader looks for?

Partial and moore

Hi Zordius,
I like you appreciate my suggestion, after work I will send you a list of think I try to implement in your library. So maybe we can discuss together for sincronize the threads. What you think?

Passing booleans to helper arguments

We should be able to pass booleans to helpers. For example, say we have this helper:

{{my_helper a=true b=1}}

LightnCandy does a lookup of true and sets a to null. I believe the expected and sane behavior would be to allow the compiler to have reserved values, such as true, false and null and pass these as-is to helpers.

Right now, the workaround I have is that I set these as variables before rendering, and some times within a given block I find myself doing @root.true to compare against true.

Maybe I'm doing something wrong? I double checked the flags but can't find a way to do this.

Unable to render partial inside conditional

The following is not possible with LightnCandy:

{{#if true}} {{> some-partial}} {{/if}}

Returns this error:

... Uncaught exception 'Exception' with message 'Unclosed token {{{#if true}}} !!' ...

The expected behavior would be to render the partial inside the block.

Template variables overridden by helper

Hello @zordius

I just noticed the following: If I have a {{term_link}} helper and I also pass term_link in the template named arguments, the value is overridden by the helper.

I consider the variable should be prioritized instead of the helper as long as it is a named argument.

What do you think?

PHP Notice Array to string conversion in compileCustomHelper

I think should be

return $context['ops']['seperator'] . static::getFuncName($context, 'ch', "$ch[0] " . $v[0]) . "\$cx, '$ch[0]', {$v[0]}, '$fn'" . ($named ? ', true' : '') . "){$context['ops']['seperator']}";

instead of

return $context['ops']['seperator'] . self::getFuncName($context, 'ch', "$ch " . $v[1]) . "\$cx, '$ch[0]', {$v[0]}, '$fn'" . ($named ? ', true' : '') . "){$context['ops']['seperator']}";

partial include from sub directories

currently (version 0.14) im unable to specify partials in sub directories to a basedir

ex: {{>my_sub_directory/test}}

it will only work if i add "my_sub_directory/" to basedir configuration. Im quite sure it worked before but around two weeks ago i stopped, i can see some changes has been made to

13ba7d4

case '>':
            self::readPartial($vars[0][0], $context);
 return true;

a quick workaround i did was to replace it with

case '>':
            self::readPartial(implode(DIRECTORY_SEPARATOR, $vars[0]), $context);
 return true;

the problem might actually be that the parser does not see "my_sub_directory/test" as one string so in $vars the string is split up into an array with 2 elements split by "/"

The option "basedir" for compile is not working.

file at C:/www/test/index.php

<?php
include 'lightncandy.php';
$phpStr = LightnCandy::compile('layout', Array(
    'basedir' => Array(
        'C:/www/test/views'
    ),
    'fileext' => Array(
        '.html'
    )
));
$renderer = LightnCandy::prepare($phpStr);
echo $renderer(array('var' => 'test'));

file at C:/www/test/views/layout.html

<h1> {{ var }} </h1>

It just output the string "layout"

Partial lookups no longer take into account paths.

Upon checking the current head, the following no longer works:

{{> partial/some-partial}}

when compiled with the following:

$x = LightnCandy::compile(
  $templateStr,
  array(
    'flags' => LightnCandy::FLAG_ERROR_EXCEPTION | LightnCandy::FLAG_STANDALONE | LightnCandy::FLAG_HANDLEBARSJS | LightnCandy::FLAG_SPVARS,
    'basedir' => array(
       'some_path/to/templates'
    )
);

The file some-partial is located in some_path/to/templates/partials/some-partial. This used to work some time ago, but now silently fails to compile. Is this new behaviour?

Lack of Handlebars.SafeString Support

In Handlebars.js, you can bypass the string escaping when using a Helper function by wrapping your return string with Handlebars.SafeString(String). However, such a thing doesn't appear to exist in lightncandy. It also provides Handlebars.Utils.escapeExpression(String) for manual escaping in such a scenario.

Support instance attribute access.

Currently, lightncandy compiles {{var.name}} to (is_array($in['var']) && isset($in(['var']['name'])) ? $in['var']['name'] : null. This does not allow for the case var might be a class instance.

It would be great to also support instance attributes - maybe by adding an additional ternary check.

Incidentally, Handlebars.php supports this. Ran into it while trying to port to lightncandy. Currently I'm working around by recursing through the context before render and converting all instances to arrays. I'd rather not have to do that, though.

{{#with}} does not work

I am trying to compile the following template:

{{#with items}}

{{/with}}

And get the error:

Unexpect token /with

Flags used for the compiler:

[\LightnCandy::FLAG_WITH]

move to handlebars.js 1.3

handlebars.js 1.3 supports new variable syntax like: {{articles.[10].[#attr]}}
so, lightncandy should version up for these new features.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.