npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

template-jsx

v1.0.0

Published

Template rendering engine for JSX

Downloads

4

Readme

JSX Templates

An intuitive way of creating templates and rendering them using the JSX syntax

With this tool you can easily create templates and render them to a string. It uses the JSX syntax from React to make templates. It is the perfect tool for backends that serve HTML content.

Installation

This is an npm package you can install in your project like this:

npm install --save template-jsx

This package is made for transpilers. So make sure to use either Babel or TypeScript. To correctly use the JSX functions, make sure to import the package in every file, like React:

import * as jsxt from "template-jsx";

When you use TypeScript, you will have to set the jsx flag to react in your tsconfig.json file. You also have to specify the factory functions:

"jsx": "react",
"jsxFactory": "jsxt.createElement",
"jsxFragmentFactory": "jsxt.Fragment",

When using Babel, you will need a JSX transform plugin and you have to specify the JSX factory.

Usage

When you have installed and configured it you are ready to go. Create some elements using JSX. Even element generator functions and fragments are supported. But try it yourself. To get the final output, you have to use the jsxt.render function. It will take the root element and return a string representation of the JSX elements:

const app = <div>
    Other elements...
</div>;
const rendered = jsxt.render(app);

For generator functions there is a special type:

const Greeting: ElementGenerator<{ name: string }> = props => <>
    Hello {props.name}!
</>;

As you can see in this example, you can use so called "fragments" to simply return text or connect multiple elements without a parent.

There are several options you can specify. The most important one is the "indent" option. It lets you set if the resulting code should be indented. It is false by default. Take a look at this:

const app = <div>sub elements</div>;
jsxt.render(app, { indent: false });
/*
<div>sub elements</div>
*/
jsxt.render(app, { indent: true });
/*
<div>
    sub elements
</div>
*/

If you don't want the indent to be set to 4 spaces, you can change the amount with the indentSize option. If you don't even want to use spaces, if you prefer tabs for example, you can use indentString. Note: indentString will be used before indentSize.

When rendering HTML pages, there is a very helpful predefined component called HtmlPage. All attributes specified will be applied to the html tag in the output. The output also includes a DOCTYPE element. All children will be put into the body element:

const app = <div>sub elements</div>;
jsxt.render(app, { indent: false });
/*
<div>sub elements</div>
*/
jsxt.render(app, { indent: true });
/*
<div>
    sub elements
</div>
*/

Using it with express

When this library is not made for frontend, whatelse would you need it for than webservers? This package has great support for express. There is an extra function called create, which takes the options and creates a renderer function. It has the HtmlPage component built-in, so if you don't pass one, it will automatically generate one. This is the basic usage:

const render = jsxt.create({
    indent: true,
    indentSize: 2
});
app.get("/", (req, res) => {
    res.send(render(<Home />))
});

If you don't need any other action in the request handler, you can just use the createHandler method from jsxt.create. The component will get the request and response object to do something with it:

const { createHandler } = jsxt.create({
    indent: true,
    indentSize: 2
});
app.get("/", createHandler(Home));

Optionally you can set a specific status code as a second parameter. It defaults to 200. When spreading the pages up to different files it might be helpful to specify a status attribute on an HtmlPage. Note: the createHandler parameter is prefered.

app.get("*", createHandler(NotFound, 404));

In this case the NotFound component can access the request object to output the incorrect path.

If you look at options.useSelfCloseTags, the jsxt.create function has the HTML self-closing tags already preset. Of course you can override it.

Special features

Bored of writing crazy expressions for conditional elements? Then you can use the builtin If Component. It takes an expression and if that expression is true it outputs the elements.

const MyApp: ElementGenerator = () => {
    return (
        <>
            <div id="header"></div>
            <div id="content"></div>
            <If cond={Math.random() > 0.98}>
                <div id="big">
                    <a href="https://www.youtube.com/watch?v=j8PxqgliIno">Watch this video</a>
                </div>
            </If>
        </>
    );
}

There is another feature called Switch that (you guessed it!) switches over different cases. The usage is really simple:

const MyApp: ElementGenerator = () => {
    return (
        <Switch expr={Math.round(Math.random() * 10)}>
            <Case c={1}>
                Case 1
            </Case>
            <Case c={2}>
                Case 2
            </Case>
            <Case c={3}>
                Case 3<br />
                Lorem ipsum dolor
            </Case>
            <Case c={4}>
                Case 4 (You can put different things than just "Case x" in here :-) )
            </Case>
            <Case c={5}>
                <a href="https://www.youtube.com/watch?v=j8PxqgliIno">Watch this video</a>
            </Case>
            <Default>
                No case was matched.
            </Default>
        </Switch>
    );
}

As you can see, there are Case elements nested in it. (Including a default case with Default)

Full list of options

  • options.indent: boolean - This option specifies if the resulting code should be formated and indented. If it is set to false, the whole output will be in one line.
  • options.indentSize: number - Sets the amount of whitespaces used for indenting. Only used when options.indent is true.
  • options.indentString: string - If you don't want to use whitespaces, if you want to use tabs for example, you can set this to your indentation string. If both options.indentString and options.indentSize are set, this one (options.indentString) will be prefered.
  • options.useSelfCloseTags: boolean | string[] - When you don't have children in an element, it will be outputed like <div />. If this is set to false, it will normally output both tags. If you even specify a list of strings, the self-closing will only be rendered for tags in that list. This is very useful when rendering web pages with img or input elements inside.

Licence

This project is licenced under the MIT licence. Read it here.