# @tpp/frag

> A simple webserver for serving pages and saving data

Latest version **1.5.0** (published 2019-05-30) · ISC license · 0 weekly downloads

## Install

```sh
npm install @tpp/frag
pnpm add @tpp/frag
yarn add @tpp/frag
bun add @tpp/frag
```

## Health

**Score 15/100 (F)** — status: abandoned.

Positive: no vulnerabilities.

Warnings: low downloads; no types; no esm support.

Negative: abandoned; low maintenance score.

## Facts

| | |
|---|---|
| Version | 1.5.0 |
| Published | 2019-05-30 |
| First published | 2019-04-21 |
| Weekly downloads | 0 |
| License | ISC |
| TypeScript types | none |
| Module format | CommonJS |
| Dependencies | 6 |
| Unpacked size | 63.3 KB |
| Known vulnerabilities | 0 |
| Install scripts | no |
| GitHub stars | 0 |
| Author | charles.lobo@gmail.com |
| Maintainers | tpp |

## Links

- npm: https://www.npmjs.com/package/@tpp/frag
- Repository: https://github.com/theproductiveprogrammer/frag
- Homepage: https://github.com/theproductiveprogrammer/frag#readme
- Issues: https://github.com/theproductiveprogrammer/frag/issues
- npm.io page: https://npm.io/package/@tpp/frag

## Dependencies (6)

- [koredb](https://npm.io/package/koredb.md) ^0.4.0
- [express](https://npm.io/package/express.md) ^4.16.4
- [shortid](https://npm.io/package/shortid.md) ^2.2.14
- [body-parser](https://npm.io/package/body-parser.md) ^1.18.3
- [serve-static](https://npm.io/package/serve-static.md) ^1.13.2
- [cookie-parser](https://npm.io/package/cookie-parser.md) ^1.4.4

## Recent versions

- 1.5.0 (latest) — 2019-05-30
- 1.4.0 — 2019-05-29
- 1.3.0 — 2019-05-25
- 1.2.1 — 2019-05-16
- 1.2.0 — 2019-05-16
- 1.1.1 — 2019-04-23
- 1.1.0 — 2019-04-22
- 1.0.0 — 2019-04-22
- 0.1.0 — 2019-04-21

## README

# Frag - The Simple Webserver

Ever wanted to quickly spin up a website? `Frag` is perfect when all you
want is to:

1. Have a site with a basic a theme and content
2. Capture user inputs

`Frag` handles generating the site for you from the templates, and
accepts user inputs from URL-parameters, POST body, or JSON-encoded
data.

![frag icon](frag.png)


## Use

First add the package to your repository using your favorite package
manager:

        $> yarn add @tpp/frag


Then require it and use it in your code.

```
'use strict'
const frag = require('@tpp/frag')

const PORT=3003
/* start the web server on port PORT
 * taking the fragments from src/
 * and generate the HTML sites in public/
 * Data will be stored in data/
 */
frag.start(PORT, 'src', 'public', 'data', (err) => {
    if(err) console.error(err)
    else console.log(`Site started on ${PORT}`)
})
```

And example layout would look like:

```
myproject/
    index.js
    src/
        _layout.html
        index.html
        page1.html
        page2.html

        different_theme/
            _layout.html
            index.html
            page3.html
            page4.html

    public/
        img/
            banner.jpg
            ...
        css/
            site.css
            ...
        js/
            site.js
            ...
        favicon.ico
        index.html
        page1.html
        page2.html
        different_theme/
            index.html
            page3.html
            page4.html
    data/
        <<data gets saved here>>
```



## Templates
Most sites have a framework/template surrounding the content:

```
    +-----------------------+   +-----------------------+
    |  FRAMEWORK/TEMPLATE   |   |  FRAMEWORK/TEMPLATE   |
    |                       |   |                       |
    |     ............      |   |     ............      |
    |                       |   |                       |
    |     ............      |   |     ............      |
    |                       |   |                       |
    |   [Actual Content     |   |   [Different Content  | . . .
    |       Fragment]       |   |       Fragment]       |
    |                       |   |                       |
    |     ............      |   |     ............      |
    |                       |   |                       |
    +-----------------------+   +-----------------------+
```

`Frag` combines the framework/template with the content to produce the
actual pages it can serve.

Both the framework/tempate and the content are simple HTML files in a
folder. The content files can start with some properties and the rest of
the file is referenced as `CONTENT`.

```
TITLE = Easter Offer
DESCRIPTION = 50% off on the best eBook this side of heaven

<div class=container>
    <div ...
</div>
```

The framework/template is a special file called
`_layout.html` that contains `$$CONTENT$$` and other `$$PROPERTIES$$`
that will be replaced by the property values in the content html files.

```
<!doctype html>
<html lang="en">
<head>
    <meta charset="utf-8">
    <title>$$TITLE$$</title>
    <meta name="description" content="$$DESCRIPTION$$">
    ...
</head>
<body>

    $$CONTENT$$

    <script src="https://code.jquery.com/jquery-3.3.1.slim.min.js"></script>

</body>
</html>
```

**NOTE: The properties are replaced LITERALLY without any HTML escaping.
This means you should make sure that the property values do not break
your HTML**

Different folders can have different `_layout.html` files for different
parts of your site. Folders without `_layout.html` files are simply
served without any processing.


## User Input and Redirects

`Frag` saves user input using the append-only log database
[Kore](https://www.npmjs.com/package/koredb). Processing of these
records can be done by adding Kore processors by accesing the `kore`
instance using `frag.kore()` and then calling
[`addProcessor()`](https://github.com/theproductiveprogrammer/koredb/blob/master/docs/START.md)

`Frag` saves any user input to the endpoint `/save`. It can optionally
take a `nxt` parameter and generate a redirect request so the browser
moves to the next page after saving the current request.

1. As URL
        site.com/save?nxt=index.html&my=data&more=data
2. As a HTML form
```
    <form action="/save" method="POST">
        <input type="text" name="name"></input>
        <input type="hidden" name="secret" value="ilikeyou"></input>
        <input type="hidden" name="nxt" value="page2.html"></input>
        <button type="submit" class="btn btn-primary">Submit</button>
    </form>
```
3. Or as an AJAX Request
```
    function save(data, cb) {
        let url_ = '/save'
        let xhr = new XMLHttpRequest()
        xhr.onreadystatechange = function() {
            if(xhr.readyState !== XMLHttpRequest.DONE) return
            if(xhr.status !== 200) cb(xhr)
            else cb(null, xhr)
        }
        xhr.open('POST', url_)
        xhr.setRequestHeader("Content-Type", "application/json")
        xhr.send(JSON.stringify(data))
    }
```


### Tracking ID
Frag automatically sets a tracking id (`trid`) to user requests so you
know which set of answers came from a given user.

# Feedback
Have something to suggest? Let me know.

---
_Source: https://npm.io/package/@tpp/frag · Machine-readable twin of the npm.io package page. Health data is recomputed on every publish._
