Comments (15)
Hi @Biont I have achieved something similar (I think) to what you are describing by compiling what I call my "layout" which is like an outer template and the "partial" independently such that the output of the compiled partial is proved as input to the compiled layout.
Does this make sense?
Basically, there is some glue code that compiles all of the partials individually and stores there result into an array that is then passed to the layout.
from lightncandy.
Hey @virtuecenter thanks for your reply.
I am not sure if I understand the part about the outer template, but you are basically suggesting precompiling everything and then just rendering the stored result.
This is probably a wise idea even if it's just for performance, and might be worth a shot to see if it solves my problem. (Well you are saying it does, so that's great).
But there's a catch: I actually do use runtime compilation at another occasion.
I wrote a "compile" helper which is used to enable handlebars when creating content (think bbCode or WordPress shortcodes). So I'll always run all text content through this helper to catch any templating going on in there.
This is of course a lot less critical to me than my custom partials, so I'll definetely give your workaround a try. However, the main problem remains
from lightncandy.
OK, I have a crazy idea for you -- but I think it would work.
Basically, in your compile-at-run helper, do a check on the string, to see if it has any handlebar variables. If so, make an instance of the other php handlebars engine and interpret the content that way. The other one is not as fast as this one, and doesn't support caching... but it is good for dynamic compilation... because that is basically all it does.
https://github.com/XaminProject/handlebars.php
from lightncandy.
That sure sounds crazy :D
I'm actually coming from the XaminProject implementation, but wanted to switch since this one looks so much easier to use. Plus, I've had problems getting helpers to work at all and did could not see where my problem was.
Well, I'm going to have another look at it, I guess. Thank you
from lightncandy.
I'm also coming from Xamin
This might help:
https://github.com/Opine-Org/Semantic-CM/blob/master/src/Manager/public/helpers/DocumentFormLeft.php
from lightncandy.
Hello all:
The short story: runtime partial (and recursive partial) will be supported in 1 week.
The long story is:
Runtime partial is my next plan , to be enhance lightncandy and make it more mustache compatible. And, I already open an issue to track it in #64.
Lightncandy try to pass mustache spec ( https://github.com/mustache/spec ) these days and already done some milestone includes: #66 , #67 , #72 , #73 . After these enhancement , lightncandy still good performance by default , and cost a little bit more to include more standard by specific flags.
Runtime partial will be supported by a new flag FLAG_RUNTIMEPARTIAL
, this will turn all partials be compiled more like helpers , which also support recursive execution. I was plan to do this today when I done some mustache related issues yesterday. :)
from lightncandy.
This is fantastic news, thank you very much!!
from lightncandy.
- After #87 , you may overwrite LightnCandy:: resolvePartial() to provide custom partial naming logic.
- Now we have flag FLAG_RUNTIMEPARTIAL , which execute partial in more dynamic way.
And, for your partial
helper , I think change the echo
to return
may fix your problem:
$helpers = array(
'partial' => function ( $name, $context ) {
$template = file_get_contents( TPL_DIR . '/' . $name . '.html' );
$php = LightnCandy::compile( $template );
$renderer = LightnCandy::prepare( $php );
return $renderer( $context[ 'data' ][ 'root' ] );
});
But, this helper do runtime compile
, it is not a good practice and do not enjoy the performance benefit of lightncandy.
Anyway, if you have any other requirement , you may open another issue, thanks.
from lightncandy.
Hey,
I spent some more time with the PHP side of things and ultimately got back to this issue.
First, thanks again for this great tool and your astonishing dedication to it. And yes, returning instead of echoing does work better indeed :)
However, I need to come back to the core issue of my first post: How do I compile templates from within helpers? I realize that much has changed with regards to compilation of partials, but my handlebars-JS templates are more or less set in stone, so I need this to work with helpers.
With the helpers array being part of the very options that boot up LightnCandy, I fear that this will prove to be an impossible task, unless the API is changed around a bit..
If I just call
LightnCandy::compile( $template );
in my custom helper, I will basically reset LightnCandy to default settings as soon as the Helper runs, right? No specific options are passed, so it will apply the default ones.
I would need to add the whole options array (including the helpers) again while I am declaring it.
Otherwise I'm missing all my settings and helpers - and even worse: I just deleted them globally
I think all that's really needed is to move the initialization logic out of the compile method, like I proposed in the OP
Bootstrap LightnCandy with
LightnCandy::init( $options);
and then LightnCandy::compile( $template ); would work the same way globally. I believe this is a simple fix. What do you think?
from lightncandy.
Well, this is what I think:
Way 1:
- store your init/config some where
- create your myCompile($template)
- inside your myCompile , get the stored init/config, mix, anything, then call compile($template, $options)
- This can be another extended class
Way 2:
1.extend lightncandy
2.override buildContext() , put your init/config there
3. and yes, you can create your own .init()
Does these 2 way are good for you?
from lightncandy.
I reviewed your question , I found the question is about 'how to keep original options be passed into another compile()' , so it is another question.
Maybe we can just do in this way:
- extend lightncandy
- override buildContext() , make it store original options inside the $context
- then when your helper wanna make another compile() , just take the original config from context , then done!
from lightncandy.
Hmmm......I missed something between step 2 to step 3. We should put something not only into $context, but also into compiled template. Look into composePHPRender() https://github.com/zordius/lightncandy/blob/master/src/lightncandy.php#L251 I think maybe I can add third param into it to make it extendable , and the third param can be set into render context.
from lightncandy.
I guess your suggestions will work, thanks. I'll whip something up after work today.
At a glance, I cannot see the problem with composePHPRenderer(). If I change things around so that the original options aren't touched when called from a helper, the $context stays the same and composePHPRenderer() never touches anything but the $context array. What am I missing?
from lightncandy.
composePHPRender()
return the final render function, and then the render function can not see compile()
context, it only see the render context
and it already hardcoded inside composePHPRender()
. So, add 3rd param is a chance to extend the render context inside the render function.
from lightncandy.
Alright, Here's what I have come up with:
class CustomCandy extends LightnCandy {
/**
* @var array<string,array|string|integer> $context Current context
*/
protected static $context;
/**
* @var bool
*/
protected static $has_inited = FALSE;
/**
* Set global options for LightnCandy
*
* @param array $options
*/
public static function init( $options = array( 'flags' => self::FLAG_BESTPERFORMANCE ) ) {
self::$context = static::buildContext( $options );
self::$has_inited = TRUE;
}
/**
* Compile handlebars template into PHP code.
*
* @param string $template handlebars template string
* @param array $options LightnCandy compile time and run time options, default is array('flags' =>
* LightnCandy::FLAG_BESTPERFORMANCE)
*
* @return string|false Compiled PHP code when successed. If error happened and compile failed, return false.
*/
public static function compile( $template, $options = NULL ) {
if ( ! is_null( $options ) || ! self::$has_inited ) {
if ( is_null( $options ) ) {
$options = array( 'flags' => self::FLAG_BESTPERFORMANCE );
}
self::$context = static::buildContext( $options );
if ( ! self::$has_inited ) {
self::$has_inited = TRUE;
}
}
if ( static::handleError( $context ) ) {
return FALSE;
}
// Strip extended comments
$template = preg_replace( static::EXTENDED_COMMENT_SEARCH, '{{!*}}', $template );
// Do first time scan to find out used feature, detect template error.
static::setupToken( self::$context );
static::verifyTemplate( self::$context, $template );
if ( static::handleError( self::$context ) ) {
return FALSE;
}
// Do PHP code generation.
static::setupToken( $context );
$code = static::compileTemplate( self::$context, static::escapeTemplate( $template ) );
// return false when fatal error
if ( static::handleError( self::$context ) ) {
return FALSE;
}
// Or, return full PHP render codes as string
return static::composePHPRender( self::$context, $code );
}
}
It seems to work so far. Note that the init() method isn't really needed, I have just made the $options parameter of compile() fully optional and added a static handle to the $context array.
I did not want to break the way LightnCandy usually works, so there's still the possibility to initialize it using just the compile() method, and using the default settings of none were passed.
That's why I added the $has_inited flag and the somewhat spaghettii-esque part at the beginning of compile()
Maybe someone will find this useful
from lightncandy.
Related Issues (20)
- Valid use for Lightncandy::prepare() HOT 6
- Nested Helpers Unavailable When Rendered
- The problem in PHP8 HOT 7
- Bad indentation in case of nested partials
- Different behaviour than Javascript when modifying context in helper HOT 1
- Hi...broken forum link
- Opencart 1.5.6 Integration
- SafeString fails with FLAG_EXTHELPER | FLAG_BESTPERFORMANCE
- Custom condition helper over payload array with conditions
- Subexpression with a string where zero spaces occur before parenthesis breaks Parser
- Custom Block Helper with blockParams
- PHP Warning: Undefined array key when trying to access unavailable key from parent context
- Possible bug with `$context['flags']['debug']`? HOT 1
- Helpers closure causes error in Laravel HOT 1
- Arrow function helpers generate invalid php code
- Parentheses in subexpression argument cause error
- .git included in vendor distribution causes errors in grunt and other tools HOT 1
- length with @root is causing parse error
- Custom each does not support `as | a index |` syntax
- Multiple `@partial-block`
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
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.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from lightncandy.