Giter Site home page Giter Site logo

umakantp / jsmart Goto Github PK

View Code? Open in Web Editor NEW
134.0 10.0 35.0 2.96 MB

jSmart is Smarty Javascript Template Engine, port of the PHP Smarty Template Engine

License: MIT License

JavaScript 95.05% Smarty 4.95%
smarty javascript jsmart template-engine smarty-template-engine javascript-template-engine

jsmart's Introduction

jSmart - Smarty template engine in JavaScript

Build Status npm version David npm npm

jSmart is a port of the Smarty Template Engine to Javascript, a JavaScript template library that supports the template syntax and all the features (functions, variable modifiers, etc.) of the well-known PHP template engine Smarty.

jSmart is written entirely in JavaScript, does not have any DOM/browser or third-party JavaScript library dependencies and can be run in a web browser as well as a standalone JavaScript interpreter or CommonJS environments like node.js.

jSmart supports plugin architecture, you can extend it with custom plugins: functions, blocks and variable modifiers, templates inclusion, templates inheritance and overriding, caching, escape HTML.

jSmart has some limited support of the PHP Smarty syntax and allows you to use the same Smarty templates on both server and client side, for both PHP and Javascript.

Play with JsFiddle demo page

Using jSmart with CDN

Always latest version (don't use in production)
https://cdn.jsdelivr.net/npm/jsmart/dist/jsmart.min.js
Current latest version (4.0.0)
https://cdn.jsdelivr.net/npm/[email protected]/dist/jsmart.min.js

jSmart with other tools

  1. Webpack:- https://www.npmjs.com/package/jsmart-loader
  2. Grunt:- https://www.npmjs.com/package/grunt-jsmart
  3. Express Js :- https://www.npmjs.com/package/jsmart-express

How to use jSmart in Node.js

  1. Install jSmart from NPM Registry
$ npm install jsmart --save
  1. Create template, use PHP Smarty syntax. Say demo.tpl
Hello {$name}
  1. Now lets read the template and compile it. jSmart object compiles the template. You can call fetch function as many times with different data you would want to assign to template.
var fs = require('fs'),
  jSmart = require('jsmart'),
  tpl = fs.readFileSync('./demo.tpl', {encoding: 'utf-8'}),
  compiledTemplate = new jSmart(tpl),
  output = compiledTemplate.fetch({name: 'World'});
  // output will be "Hello world"

console.log(output);
  1. Execute the file.
$ node demo.js

How to use jSmart in browser

  1. Include jSmart library Javascript file in your header.
<html>
  <head>
    <script language="javascript" src="jsmart.js"></script>
  </head>
  1. Create template, use PHP Smarty syntax. Put the template's text in <script> with the type="text/x-jsmart-tmpl" so a browser will not try to parse it and mess it up.
  <script id="test_tpl" type="text/x-jsmart-tmpl">
    Hello {$name}
  </script>
  1. Create new object of jSmart class, passing the template's text as it's constructor's argument than call fetch(data), where data is an JavaScript object with variables to assign to the template
<script>
  var content = document.getElementById('test_tpl').innerHTML;
  var compiled = new jSmart(content);
  var output = compiled.fetch({name: 'world'});
  // output will be "Hello world"
</script>

How to use jSmart using Require.js

  1. If you have configured and installed Require.js it easy to load jSmart and use it. Load jSmart.js file in the browser/environment and it already makes use require js to define module, you got to just include it.
define(['jSmart'], function (jSmart) {
  var tplText = 'Hello {$name}';
  var compiled = new jSmart(tplText);
  var output = compiled.fetch({name: 'world'});
  // output is "Hello world"
});
  1. You can also make use Require.js text plugin to load templates.
define(['jSmart', 'text!some/good/template.tpl'], function (jSmart, goodTpl) {
  var compiled = new jSmart(goodTpl);
  var output = compiled.fetch({name: 'world'});
  // output is "Hello world"
});

DOCUMENTATION

https://github.com/umakantp/jsmart/wiki

CONTRIBUTIONS & TESTS

  • Pull request Best is open a issue first. Then send a pull request referencing the issue number. Before sending pull request make sure you add test case for the fix. Make sure all test cases are passing and eslint tests pass.

  • Test cases:- grunt karma

  • ES Lint tests:- grunt eslint

  • Run lint, run test, build, compress, distribution package and update examples in one command:- grunt

LICENSE

MIT

NOTICE

Project originally was created by miroshnikov. Since author was not active on project very frequently. I have forked and planned on pushing further improvements and features on my own fork.

jsmart's People

Contributors

codeurweb avatar jwellner avatar miroshnikov avatar mofux avatar umakantp avatar xadrianautofact 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

jsmart's Issues

Types

Please add types for integrated with typescript

How to use variables in include?

I try to use this template code (for Node JS):

res.render('index', {fname: 'include.smarty'});

{include file="$fname"}

Result:

Error: ENOENT: no such file or directory, open 'C:\OSPanel\domains\express\partials\$fname'

If I use it like this:

{include file="include.smarty"}

Returns normal response.

What could be the problem when using variables in include?

jSmart conditional & loop statement are not working with React-JS.

In my React-JS Project, I am trying to use the smarty template. It is working for variables but it is not working at all for the loop and conditional statement.
I have following code written in my template :
Following Data From Template
<div>
Simple Data Passing <br/>
<h1>{$data}</h1>
<hr/>
for loop code : <br/>
{$ar = ['a','b','c','d']}
{for $i=0 to $ar|count-1 max=3}
{$ar[$i]}
{/for}
<hr />
if statement : <br/>
{assign var='xyz' value="1"}
{if '1' eq $xyz }
if condition working
{else}
if condition is not working
{/if}
</div>

Which is giving following output :
<div>Simple Data Passing <br>
<h1>Hello World</h1>
<hr>
for loop code : <br>

<hr>
if statement : <br>
{if '1' eq $xyz }
if condition working
{else}
if condition is not working
{/if}
</div>

Here I am passing the $data as "Hello World" it is working properly, but the below of for each is not working.
So could you please help me with this?

{include file="./templates/header.html"} not working

JS Code:
var fs = require('fs'),
path = require('path'),
jSmart = require('jSmart');

var tpl = fs.readFileSync(path.join(process.cwd(),'/templates/Expenses.html'), {encoding: 'utf-8'});
console.log(tpl)
var compiledTemplate = new jSmart(tpl);
console.log(compiledTemplate.fetch({Title: "Expenses - jSmart"}));

The Expenses.html loads OK but the include above throws:

Error: No template for ./templates/header.html

Have tried all combinations of file names in the template file

Modifier plugin names conflict with template variable names

If there is both a modifier and a variable in a scope, the two will conflict, and the modifier won't be accessible within the data section.

Example:

jSmart.prototype.registerPlugin(
    'modifier',
    'round',
    function(num, digits)
    {
        var multiplier = Math.pow(10, digits);
        return Math.round(num * multiplier) / multiplier;
    }
);

var tpl = new jSmart('{$round} {$num|round:2}');
tpl.fetch({a: 2.1324, round: 2});

Bug was reported at https://code.google.com/p/jsmart/issues/detail?id=21

Issue with multiple comments in template

    it('test comments', function () {
      var t = new jSmart('Testing {* testing *}, does it {* multiple comments *}work?')
      expect(t.fetch()).toBe('Testing , does it work?')
    })

Result:

Error: Unclosed /{\*/* in src/parser/parser.js (line 667)
removeComments@src/parser/parser.js:667:54
getTree@src/parser/parser.js:54:37
getParsed@src/parser/parser.js:83:30
parse@src/core.js:199:46
jSmart@src/core.js:82:15
test/basic-spec.js:43:25

recursive include not working

I have the following error when trying to do a recursive include in a menu template.
This does work with the other jsmart in github but that one is way older. - https://github.com/miroshnikov/jsmart

Uncaught (in promise) SyntaxError: Invalid regular expression: /^\s*(/foreach)\s*$/: Stack overflow
    at String.match (<anonymous>)
    at Object.findTag (jsmart.js:283)
    at Object.findCloseTag (jsmart.js:329)
    at Object.parse (jsmart.js:199)
    at Object.getTree (jsmart.js:130)
    at Object.loadTemplate (jsmart.js:715)
    at Object.parse (jsmart.js:1209)
    at Object.parse (jsmart.js:211)
    at Object.parse (jsmart.js:1267)
    at Object.parse (jsmart.js:200)
 <script  id="category-tree" type="text/html"> 
 		{foreach $data as $cat}
 		<li><a href="#">{$cat.category_name}</a>
 			{if $cat.nodes}
 			<ul>
 				{include file='category-tree' data=$cat.nodes}
 			</ul>
 			{/if}
 		</li>
 		{/foreach}
 	</script>

Include template without compiling

Hi!

So I was wondering how I can include a template to be compiled by jsmart, in another template which is to be compiled by smarty (php). In order to do that I would want to use the include-tag, but tell smarty to NOT compile the one I include, ie. just output it as a string.

At the moment using {include ...} always results in a undefined variable notice for me:
"Fatal error: PHP notice in file /var/www/[...]/templates/compiled/servers.php (386): Undefined index: id".

I already skimmed the docs, but could not find anything related.
I want to include a template like shown in your examples in a smarty compiled template:

File: servers.tpl - compiled with php-smarty.

<script id="serversListItem" type="text/x-jsmart-tmpl">
    {include file='serversListItem'}
</script>

Thank you!

Bug with foreach and eval

I have an issue in 2.13.1 with this construct:

{foreach $foos as $foo}blablablabla: {eval $foo}
{/foreach}

All my lines inside the loop are concatened, seems the \r\n (DOS) is eaten in the loop.
But if i had one character at end like: blablablabla: {eval $foo}A
the loop runs just correct (CRLF are done).
Also it runs correct with a standart variable without the eval like blablablabla: {$bar}
I dont now where the CRLF disappear

Blocks inside blocks dont work?

Hello there,

block nesting like this does not work:
{block name="header"} <div class="menu"> {block name="menu-items"} <div class="item"> menu </div> {/block} </div> {/block}

is there a way to fix this?

Assignment in a comparison is not functioning

Template example: "{if $info = "test"}{$info}{/if}"
Expected result: "test"
Actual result: empty string, no execution of code inside the "if" block.

This construction is functioning in PHP version of Smarty.

Code to reproduce:

<script> var templateText = '{if $info = "test"}{$info}{/if}'; window.onload = function() { var template = new jSmart(templateText); document.getElementById('test').innerHTML = template.fetch(); }; </script>

strip_tags

in the strip_tags modifier, i dont understand your code:

return (new String(s)).replace(/<[^>]*?>/g, addSpace ? ' ' : '');

Would not it be:

return (new String(s)).replace(/<[^>]*>/g, addSpace ? ' ' : '');

without the '?'.

No dump plugin

I submitted a pull request with a basic implementation of the dump plugin
#27

{capture} block is not working in foreach

{foreach $items as $item}
    {capture name="data"}
...
    {/capture}
{/foreach}

throws the following error:

... (trunk)/node_modules/jsmart/dist/jsmart.js:1540
          tmp = this.buildInFunctions[node.name].process.call(this, node, data)
                                                 ^

TypeError: Cannot read property 'process' of undefined

After some debugging I noticed node.name is changed in capture process method causing it somehow to lose reference to the process method.

node.name = ('cap-' + node.params.name)

When I comment out this line it works as expected but i'm not sure if there is a reason node.name is changed?

Incorrect evalution order

The following code seems to be working properly.

jSmart = require('jsmart');
data = {
  array: [1, 2, 3],
  count: (array) => array.length
};

tmpl = new jSmart('{count($array)}');
console.log(tmpl.fetch(data));    // -> 3

tmpl = new jSmart('{if count($array)}OK{else}NG{/if}');
console.log(tmpl.fetch(data));    // -> OK

However, the following code does not work as expected.

tmpl = new jSmart('{if count($array) > 0}OK{else}NG{/if}');
console.log(tmpl.fetch(data));    // -> NG

Apparently, it seems that count modifier is working instead of my count method.

tmpl = new jSmart('{count($array)}');
console.log(tmpl.fetch({
  array: [1, 2, 3],
  count: (array) => 'My count method'
}));
// -> 3

Can I use my count method?

undefined problem with object childrens

if I have undefined object all childrens of it are undefined. I dont want to see undefined on non existing object childs. I would like to have undefined changed to '' and NaN to 0 or also to empty string.

Built-in functions not running?

I'm assuming that I'm doing something completely wrong here. I'm trying to move some simple templates over to node. But, this one isn't firing and it's not clear from the docs or the source why this isn't working. I'm using 3.1.0

const jsmart = require('jsmart'); const template = '<td><strong>Date Collected: </strong>{strtotime($collection_date)|date_format:"m/d/Y"}</td>'; const compiled = new jsmart(template); console.log(compiled.fetch({ collection_date: '2020-01-01' }));

<td><strong>Date Collected: </strong>m/d/Y</td>

`getTemplate` broken when parsing multiple templates

In a situation where you're parsing multiple files through jSmart, I've found that in the event that your template has an extends tag, only the first one get parsed correctly.

This occurs when using in a build process like:
https://github.com/timkelty/gulp-jsmart
https://github.com/hereandnow/grunt-jsmart

I've found that if I add nocache = true; to the top of the getTemplate function, things seem to work fine.

Any idea?

Possibly related to: #11

Syntax error in readme.md

in the "How to use jSmart in Node.js" chapter in number 3 (and 4). Nothing major but was rather confusing to a JS/Node beginner like me. Took me a while to figure out what was wrong.

var fs = require(fs);

should be

var fs = require('fs');

jsmart should support AMD and CMD

how can i use jsmart when there is not module.exports = jSmart; in jsmart.js.
and i dont think set fetch in String.prototype is a good way.

fetch returns empty when the same template calls it more than once

I call fetch successfully at the first time under nodejs, but after that it always returns empty string. I think there may be bugs due to caching after I read the source of jSmart.

jSmart.prototype.getTemplate = function(name){
    return xxx; //some parent content
}

var t1 = new jSmart('xxx'); //a template contains "extends"
var first = t1.fetch({xxx:'xxx'});//first is not empty
var t2 = new jSmart('xxx');//Same template as t1
var second = t2.fetch({xxx:'xxx'});//Same content as t1, but second is empty now

Unexpected [object Object] output when variable does not exist

I would expect it not to print [object Object] when the variable does not exist. Is this expected behavior or a bug?

Code

var jSmart = require('jsmart');

var compiledTemplate = new jSmart("Variable does not exist: {$variable}");
console.log(compiledTemplate.fetch({}));

Output:

Variable does not exist: [object Object]

smarty comments don't work with some custom delimiters like {{ }}

have a look at http://www.smarty.net/docs/en/language.basic.syntax.tpl

{* this is a comment for smarty *}

At the present I use the original php templates for jsmart, so I don't have every of the many files twice. But I can't use them because they are full of comments which result in presenting empty delimiters ({}) in the output

edit:
OK I have to correct some things:

The Comments are working with the original delimiters. In our project we use {{ and }} With this delimiters the comments don't work (the delimiters appear in the output). Look the post above

I will change the subject of this issue

window is not defined

When using this module through node.js, some of the checks for window do fail. The reason is that checking the existence of a global window object cannot be done via if (window), because if window does not exist, it will throw an error. Instead, you should check for window existence via if (typeof window === 'object'), which will not throw.

I'm happy to create a PR if you like.

{master file="sometemplte.tpl"} must read the master file template

This is a requested feature and not a bug or issue with the templating engine.

Can the following be achieved so that the Smarties can be used alongwith Sharpy in .NET as well for master pages as used by Sharpy.
Refer documentation at http://sharpy.codeplex.com/
Refer Master page docs at http://sharpy.codeplex.com/wikipage?title=masterpages&referringTitle=Documentation

Regular Page Template:

{master file='Layout.smarty' title="Title"}
<h2>Hello World</h2>

MASTER Page or Layout.smarty:

<!DOCTYPE html>
<html>
<head>
    <title>{$title}</title>
	<meta charset="utf-8" />
</head>
<body>
	{$content}
</body>
</html>

Expected output:

<!DOCTYPE html>
<html>
<head>
    <title>Title</title>
	<meta charset="utf-8" />
</head>
<body>
	<h2>Hello World</h2>
</body>
</html>

Passing context to modifier

Hey,

What do you think about passing the current context to a modifier as the "this" instance instead of the function itself as the context?

I mean replace this with:
return fname.apply(data, paramData)

This will allow more complex custom modifiers that needs more information to return the output.
Do you think it has any downside?

Thanks,
Bnaya

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.