{"id":14986786,"url":"https://github.com/will123195/bleh","last_synced_at":"2025-09-08T05:41:26.614Z","repository":{"id":35925217,"uuid":"40213126","full_name":"will123195/bleh","owner":"will123195","description":"A web framework with automatic Browserify + Less + Express + Handlebars","archived":false,"fork":false,"pushed_at":"2023-11-30T14:28:11.000Z","size":138,"stargazers_count":48,"open_issues_count":20,"forks_count":1,"subscribers_count":3,"default_branch":"master","last_synced_at":"2025-03-25T18:54:03.346Z","etag":null,"topics":["browserify","express","handlebars","less"],"latest_commit_sha":null,"homepage":"","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/will123195.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2015-08-04T22:59:11.000Z","updated_at":"2023-03-08T04:34:55.000Z","dependencies_parsed_at":"2024-06-21T14:13:08.499Z","dependency_job_id":"a02c97c5-fbed-4699-850b-6d27380cea5f","html_url":"https://github.com/will123195/bleh","commit_stats":{"total_commits":166,"total_committers":3,"mean_commits":"55.333333333333336","dds":0.01807228915662651,"last_synced_commit":"8e07799aec0719cf31810bf72edd82574fbb6d43"},"previous_names":[],"tags_count":34,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/will123195%2Fbleh","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/will123195%2Fbleh/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/will123195%2Fbleh/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/will123195%2Fbleh/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/will123195","download_url":"https://codeload.github.com/will123195/bleh/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248287808,"owners_count":21078786,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["browserify","express","handlebars","less"],"created_at":"2024-09-24T14:13:33.057Z","updated_at":"2025-04-11T23:01:50.328Z","avatar_url":"https://github.com/will123195.png","language":"JavaScript","readme":"# bleh\n\n[![Build Status](https://travis-ci.org/will123195/bleh.svg)](https://travis-ci.org/will123195/bleh)\n\nA web framework with automatic Browserify + Less + Express + Handlebars.\n\n[![bleh](bleh.gif)](https://github.com/will123195/bleh)\n\n- **Browserify** is automatic\n- **Less** compilation is automatic\n- **Express** routing is automatic\n- **Handlebars** precompilation is automatic for both server and browser\n- Serves static files\n- Secure cookie-based sessions\n\n## Quick start\n\n```\nnpm install -g bleh\nmkdir my-app \u0026\u0026 cd my-app\nnpm init\nbleh init\nnpm run dev\n```\n\n## Usage\n\n```js\nconst bleh = require('bleh')\nconst express = require('express')\nconst app = express()\nconst port = process.env.PORT || 8080\napp.use('/', bleh())\napp.on('ready', () =\u003e {\n  app.listen(port, () =\u003e {\n    console.log([\n      'My App',\n      `Running: http://localhost:${port}`,\n      `NODE_ENV: ${process.env.NODE_ENV}`,\n    ].join('\\n'))\n  })\n})\n```\n\n## File structure\n\n```\n├─ layouts/\n├─ node_modules/\n├─ pages/\n│  ├─ home/\n│  │  ├─ home.browserify.js\n│  │  ├─ home.less\n│  │  ├─ home.node.js\n│  │  └─ home.html\n│  └─ $name/\n│     └─ $name.node.js\n├─ partials/\n├─ public/\n│  ├─ dist/\n│  └─ robots.txt\n├─ test/\n├─ server.js\n└─ package.json\n```\n\nSee also the [sample app](sample-app).\n\n#### pages/\n\nRoutes are generated automatically based on the `pages/` folder structure. Each page has a [controller](#controllers) (`.node.js` file) and normally has `.html`, `.less` and `.browserify.js` files located together in that page's folder.\n\nThe page's `js` and `css` files are automatically embedded via the `html5` *layout*.\n\nWords beginning with `$` in the page name are URL params. See [example](#pagesuserusernodejs).\n\n#### layouts/\n\nYou can set the layout for the page by calling [`$.layout(name)`](#controller-methods-and-properties). Layouts have automatic Browserify, LESS and Handlebars compilation just like [pages](#pages) but the layout's `.html` file must contain `{{{main}}}`.\n\n#### partials/\n\nPartials can be included in other templates. Partials are just plain ol' handlebars templates. Put your Handlebars helper methods in `lib/handlebars-helpers.js`.\n\n```html\n\u003cdiv\u003e\n  {{\u003e partials/hello}}\n\u003c/div\u003e\n```\n\n#### public/\n\nAll files in the `public` folder are served as static files.\n\n## Build\n\nThe build process generates the `public/dist/` folder containing the `js` and `css` for your app.\n\nThe build is generated at runtime (except in `production`) and the app's `ready` event fires when the build is complete.\n\nIn the `production` environment, the build step is skipped and the `ready` event fires immediately to avoid a brief delay starting the app.\n\nWhen deploying to production, `bleh build` will run automatically after `npm install` (i.e. you should have `\"postinstall\": \"bleh build\"` in `package.json`).\n\nUse `npm run dev` for development so your app restarts and rebuilds when a source file changes.\n\n#### Browserify\n\nIf you add your commonly used client-side npm modules to the [`browserifyCommonDependencies`](sample-app/package.json) array in your `package.json`, then an [external browserify bundle](https://github.com/substack/node-browserify#multiple-bundles) will be used. This will reduce the size of your page-specific `js` bundles.\n\n#### Less\n\nYou can [reference](http://lesscss.org/features/#import-options-reference) any other `.less` file to gain access to its variables/classes/mixins. For example, the [`html5`](shared/layouts/html5) layout provides a `.clearfix` style for convenience.\n\n```less\n@import (reference) 'layouts/html5/html5.less';\n.something {\n  .clearfix;\n  color: @black;\n}\n```\n\n#### Handlebars\n\nYour handlebars helpers will work on both the server and client if you specify them in `lib/handlebars-helpers.js` (assuming you're using the `html5` layout).\n\nFor example: [`handlebars-helpers.js`](sample-app/lib/handlebars-helpers.js)\n\nAlso, if you're using the `html5` layout, you can use `window.render()`  to render any of your `.html` templates on the client side. You can see the templates you have available with `console.log(Handlebars.templates)`.\n\n```js\nvar html = window.render('partials/hello', data)\n```\n\n## Options\n\nAll options are optional.\n\n```js\nvar app = bleh({\n  // default options\n  dist: 'public/dist',\n  helpers: {},\n  home: '/home',\n  https: false,\n  log: console.log,\n  root: __dirname,\n  sessions: false // {secret: 'My EncRypT10n k3Y'}\n})\n```\n\n- **dist** - The folder to contain the build files.\n- **helpers** - This object gets merged into the context of the [controller](#controllers).\n- **home** - The page (uri) to be used as the homepage. By default, `/home` redirects to `/`.\n- **https** - This option forces a redirect to `https` only in production.\n- **log** - The function for log output. Defaults to `console.log`.\n- **root** - The path to the root folder of your app (which contains `pages/`). See [file structure](#file-structure).\n- **sessions** - Configuration for cookie-based sessions. To enable sessions, you need a `secret` value. See [client-sessions](https://www.npmjs.com/package/client-sessions).\n\n## Controllers\n\nThe [build](#build) automatically creates routes for `.node.js` files (controllers) that exist in the [`pages/`](#pages) folder.\n\nFor example:\n\n##### pages/beep.json.node.js\n```js\n// uri: /beep.json\nmodule.exports = function ($) {\n  $.send({\n    beep: 'boop'\n  })\n}\n```\n\n##### pages/hello/hello.node.js\n```js\n// uri: /hello\nmodule.exports = function ($) {\n  $.title = 'Hello' // set data to be rendered\n  // add additional css or js to the page\n  $.css.push('//maxcdn.bootstrapcdn.com/font-awesome/4.4.0/css/font-awesome.min.css')\n  $.layout('website') // specify the layout and call its controller function\n  $.render() // send the rendered html\n}\n```\n\n##### pages/$user/$user.node.js\n```js\n// uri: /will123195\nmodule.exports = function ($) {\n  console.log($.$user) // will123195\n  $.render()\n}\n```\n\n##### layouts/website/website.node.js\n```js\nmodule.exports = function ($) {\n  $.now = Date.now()  // set data for all pages using this layout\n  $.layout('html5')   // html5 boilerplate + link css \u0026 js\n}\n```\nEach layout has a controller that runs when the [`layout`](#layout) method is invoked. A generic [`html5`](shared/layouts/html5) layout is provided that magically links the corresponding `css` and `js` onto the page if invoked.\n\n#### Controller methods and properties\n\n- `accessDenied()` - sends 403 response\n- `body` - the request body (i.e. POST data)\n- `error(err)` - sends 400 response\n- `get(fn)` - calls `fn` if request method is GET\n- `layout(name)` - invokes a layout\n- `notFound()` - sends 404 response\n- `post(fn)` - calls `fn` if request method is POST\n- `query` - the parsed querystring\n- `redirect([301|302], uri)` - sends redirect response\n- `render()` - sends rendered html using `this` data\n- `req` - the http request object\n- `res` - the http response object\n- `send(obj|str)` - sends a text or json response\n- `session` - the values encrypted in a cookie\n- `set(helpers)` - merges new properties into this context\n- `templates` - the array of precompiled template functions\n- `view(name)` - changes the default template to be `render()`ed\n\nAdditional `helpers` specified in the [options](#options) are merged into the controllers' context. For example, adding your `db` as a helper will make it accessible in all controllers as `this.db`.\n\nNote: `req`, `res` and `templates` are hidden for convenience so you can `console.log(this)` without so much noise.\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fwill123195%2Fbleh","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fwill123195%2Fbleh","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fwill123195%2Fbleh/lists"}