{"id":14967744,"url":"https://github.com/werty1001/bempug","last_synced_at":"2025-10-25T21:31:57.269Z","repository":{"id":50684505,"uuid":"73013626","full_name":"werty1001/bempug","owner":"werty1001","description":"Simple mixins to help you writing code on BEM methodology in pug or jade projects.","archived":true,"fork":false,"pushed_at":"2017-03-23T15:36:59.000Z","size":29,"stargazers_count":16,"open_issues_count":2,"forks_count":0,"subscribers_count":5,"default_branch":"master","last_synced_at":"2025-01-31T10:51:11.237Z","etag":null,"topics":["bem","html","jade","mixins","pug"],"latest_commit_sha":null,"homepage":"","language":"HTML","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/werty1001.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}},"created_at":"2016-11-06T19:27:30.000Z","updated_at":"2025-01-05T18:43:15.000Z","dependencies_parsed_at":"2022-08-27T23:30:44.789Z","dependency_job_id":null,"html_url":"https://github.com/werty1001/bempug","commit_stats":null,"previous_names":[],"tags_count":1,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/werty1001%2Fbempug","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/werty1001%2Fbempug/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/werty1001%2Fbempug/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/werty1001%2Fbempug/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/werty1001","download_url":"https://codeload.github.com/werty1001/bempug/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":238212424,"owners_count":19434955,"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":["bem","html","jade","mixins","pug"],"created_at":"2024-09-24T13:38:32.843Z","updated_at":"2025-10-25T21:31:51.986Z","avatar_url":"https://github.com/werty1001.png","language":"HTML","funding_links":[],"categories":[],"sub_categories":[],"readme":"# BemPug\n\n[![GitHub license](https://img.shields.io/badge/license-MIT-blue.svg?style=flat-square)](https://raw.githubusercontent.com/werty1001/bempug/master/LICENSE) [![npm](https://img.shields.io/npm/v/bempug.svg?style=flat-square)](https://www.npmjs.com/package/bempug) [![npm](https://img.shields.io/npm/dt/bempug.svg?style=flat-square)](https://www.npmjs.com/package/bempug)\n\nSimple mixins to help you writing code on [BEM](https://en.bem.info/) methodology in [pug](https://pugjs.org/) or jade projects.\n\n---\n\n\u003e You like BEM? Try [BemGo](https://github.com/werty1001/bemgo) — starter kit for developing BEM apps using Gulp and Webpack.\n\n---\n\n### Anchors\n[Install](#install) | [Mixins](#mixins) | [Examples](#examples) | [Helpers](#helpers) | [Changelog](#changelog)\n\n---\n\n### Install\n\nInstall from npm:\n```sh\nnpm i bempug -D\n```\nThen include `index` file to your pug or jade project:\n```Jade\ninclude ../../node_modules/bempug/index\n```\n\n---\n\n### Mixins\n\nBlock mixin:\n\n```Pug\n+b( name, data, tag )\n```\n\n- **name** `String`\n- **data** `String or Object`\n  - **data.m** `String` — block modifier\n  - **data.p** `Boolean` — disable parent mode\n  - **data.e** `Array or String` — mix block with element\n  - **data.b** `Array or String` — mix block with another block\n  - **data.t** `String` — block tag\n  - **data.s** `String` — block separators\n- **tag** `String`\n\n\u003e If data argument is String it will be a modifier.\n\n\u003cbr\u003e\n\nElement mixin:\n\n```Pug\n+e( name, data, tag )\n```\n\n- **name** `String`\n- **data** `String or Object`\n  - **data.m** `String` — element modifier\n  - **data.p** `String` — parent block\n  - **data.e** `Array or String` — mix element with another element\n  - **data.b** `Array or String` — mix element with block\n  - **data.t** `String` — element tag\n  - **data.s** `String` — element separators\n- **tag** `String`\n\n\u003e If data argument is String it will be a modifier.\n\n---\n\n### Examples\n[Block](#block) | [Element](#element) | [Modifier](#modifier) | [Tag](#tag) | [Mix](#mix) | [Separators](#separators)\n\n---\n\n### Block\nSimple example:\n```Pug\n+b( 'block' )\n    +e( 'element' ) Text\n```\n```HTML\n\u003cdiv class=\"block\"\u003e\n    \u003cdiv class=\"block__element\"\u003eText\u003c/div\u003e\n\u003c/div\u003e\n```\n\nYou can to disable parent mode and element will ignore this block:\n```Pug\n+b( 'header' )\n    +b( 'grid', {p: false} ) // or short {p:0}\n        +e( 'logo' ) Logo\n```\n```HTML\n\u003cdiv class=\"header\"\u003e\n    \u003cdiv class=\"grid\"\u003e\n        \u003cdiv class=\"header__logo\"\u003eLogo\u003c/div\u003e\n    \u003c/div\u003e\n\u003c/div\u003e\n```\n\n---\n\n### Element\n\nElement depends on parent block:\n```Pug\n+b( 'content' )\n    +e( 'layout' ) Content\n```\n```HTML\n\u003cdiv class=\"content\"\u003e\n    \u003cdiv class=\"content__layout\"\u003eContent\u003c/div\u003e\n\u003c/div\u003e\n```\nYou can set parent block for element directly:\n```Pug\n+b( 'content' )\n    +e( 'layout', {p: 'page'} ) Content\n```\n```HTML\n\u003cdiv class=\"content\"\u003e\n    \u003cdiv class=\"page__layout\"\u003eContent\u003c/div\u003e\n\u003c/div\u003e\n```\n\n---\n\n### Modifier\n\nBlock and element have modifier:\n```Pug\n+b( 'alert', 'success' )\n    +e( 'text', 'bolder' ) Success\n```\n```HTML\n\u003cdiv class=\"alert alert--success\"\u003e\n    \u003cdiv class=\"alert__text alert__text--bolder\"\u003eSuccess\u003c/div\u003e\n\u003c/div\u003e\n```\n\nBlock and element have more than one modifier:\n```Pug\n+b( 'alert', 'success.active' )\n    +e( 'text', 'bolder.italic' ) Success\n```\n```HTML\n\u003cdiv class=\"alert alert--success alert--active\"\u003e\n    \u003cdiv class=\"alert__text alert__text--bolder alert__text--italic\"\u003eSuccess\u003c/div\u003e\n\u003c/div\u003e\n```\n\nAlso, you can set modifiers in `Object`:\n```Pug\n+b( 'alert', {m: 'success.active'} ) Success\n```\n```HTML\n\u003cdiv class=\"alert alert--success alert--active\"\u003eSuccess\u003c/div\u003e\n```\n\n---\n\n### Tag\n\nDefault tag is **div**, but you can set it directly:\n```Pug\n+b( 'news', {}, 'article' )\n    +e( 'title', {}, 'h1' ) Title\n\n// Or in data Object\n\n+b( 'news', {t: 'article'} )\n    +e( 'title', {t: 'h1'} ) Title\n```\n```HTML\n\u003carticle class=\"news\"\u003e\n    \u003ch1 class=\"news__title\"\u003eTitle\u003c/h1\u003e\n\u003c/article\u003e\n```\n\nSometimes mixin can be smart and tag depends on parent or attributes:\n```Pug\n+b( 'list', {t: 'ul'} )\n    +e( 'item' ) My item 1\n    +e( 'item' ) My item 2\n    +e( 'item' ) My item 3\n\n+b( 'link' )(href='https://www.npmjs.com/package/bempug')\n    +b( 'text' ) My text\n```\n```HTML\n\u003cul class=\"list\"\u003e\n    \u003cli class=\"list__item\"\u003eMy item 1\u003c/li\u003e\n    \u003cli class=\"list__item\"\u003eMy item 2\u003c/li\u003e\n    \u003cli class=\"list__item\"\u003eMy item 3\u003c/li\u003e\n\u003c/ul\u003e\n\n\u003ca class=\"link\" href=\"https://www.npmjs.com/package/bempug\"\u003e\n    \u003cspan class=\"text\"\u003eMy text\u003c/span\u003e\n\u003c/a\u003e\n```\n\nAlso, you can use `tagByName` global option for set default tag by name:\n\n```Pug\n- BEMPUG.tagByName = {list: 'ul', form: 'form', fields: 'fieldset'};\n\n+b( 'list' )\n    +e( 'item' ) Item\n    +e( 'item' ) Item\n    \n+b( 'form' )\n    +e( 'fields' ) Fields\n```\n```HTML\n\u003cul class=\"list\"\u003e\n    \u003cli class=\"list__item\"\u003eItem\u003c/li\u003e\n    \u003cli class=\"list__item\"\u003eItem\u003c/li\u003e\n\u003c/ul\u003e\n\n\u003cform class=\"form\"\u003e\n    \u003cfieldset class=\"form__fields\"\u003eFields\u003c/fieldset\u003e\n\u003c/form\u003e\n```\n\n---\n\n### Mix\n\nBlock is mixed with element:\n```Jade\n+b( 'title', {e: 'article'} ) Title\n```\n```HTML\n\u003cdiv class=\"title article__title\"\u003eTitle\u003c/div\u003e\n```\n\nYou can set name of element in mix with colon:\n```Pug\n+b( 'title', {e: 'article:my-name'} ) Title\n```\n```HTML\n\u003cdiv class=\"title article__my-name\"\u003eTitle\u003c/div\u003e\n```\n\nBlock is mixed with two elements:\n```Pug\n+b( 'title', {e: ['article', 'content']} ) Title\n```\n```HTML\n\u003cdiv class=\"title article__title content__title\"\u003eTitle\u003c/div\u003e\n```\n\nAlso, you can use ampersand `\u0026` sign as parent block reference:\n```Pug\n+b( 'news' )\n    +b( 'title', {e: '\u0026'} ) Title\n    +b( 'text', {e: '\u0026:description'} ) Text\n```\n```HTML\n\u003cdiv class=\"news\"\u003e\n    \u003cdiv class=\"title news__title\"\u003eTitle\u003c/div\u003e\n    \u003cdiv class=\"text news__description\"\u003eText\u003c/div\u003e\n\u003c/div\u003e\n```\n\nBlock is mixed with element which has modifiers:\n```Pug\n+b( 'title', {e: 'news|bolder.size-m'} ) Title\n```\n```HTML\n\u003cdiv class=\"title news__title news__title--bolder news__title--size-m\"\u003eTitle\u003c/div\u003e\n```\n\nElement is mixed with another element:\n```Pug\n+b( 'footer' )\n    +e( 'bottom', {e: 'page'} )\n```\n```HTML\n\u003cdiv class=\"footer\"\u003e\n    \u003cdiv class=\"footer__bottom page__bottom\"\u003e\u003c/div\u003e\n\u003c/div\u003e\n```\n\nElement is mixed with block:\n```Pug\n+b( 'footer' )\n    +e( 'bottom', {b: 'grid'} )\n```\n```HTML\n\u003cdiv class=\"footer\"\u003e\n    \u003cdiv class=\"footer__bottom grid\"\u003e\u003c/div\u003e\n\u003c/div\u003e\n```\n\nBlock is mixed with another block:\n```Pug\n+b( 'article', {b: 'news'} ) Content\n```\n```HTML\n\u003cdiv class=\"article news\"\u003eContent\u003c/div\u003e\n```\n\nBlock is mixed with another block which has modifiers:\n```Pug\n+b( 'article', {b: 'news|first'} ) Content\n```\n```HTML\n\u003cdiv class=\"article news news--first\"\u003eContent\u003c/div\u003e\n```\n\nBlock is mixed with two blocks which have modifiers:\n```Pug\n+b( 'article', {b: ['news|first','fixed|active']} ) Content\n```\n```HTML\n\u003cdiv class=\"article news news--first fixed fixed--active\"\u003eContent\u003c/div\u003e\n```\n\n---\n\n### Separators\nYou can change global separators:\n```Pug\n- BEMPUG.modifier = '_';\n- BEMPUG.element = '__';\n\n+b( 'alert', 'success.active' )\n    +e( 'text', 'bolder.italic' ) Success\n```\n```HTML\n\u003cdiv class=\"alert alert_success alert_active\"\u003e\n    \u003cdiv class=\"alert__text alert__text_bolder alert__text_italic\"\u003eSuccess\u003c/div\u003e\n\u003c/div\u003e\n```\n\nAlso, you can set separators for each block and ignore global settings `'modifier|element'`:\n```Pug\n+b( 'news', {e: 'content', m: 'first', s: '---|___' } )\n    +b( 'text', {e: true, m: 'bolder'} ) Text\n```\n```HTML\n\u003cdiv class=\"news news---first content___news\"\u003e\n    \u003cdiv class=\"text text---bolder news___text\"\u003eText\u003c/div\u003e\n\u003c/div\u003e\n```\n\n---\n\n### Helpers\n[Get current block](#get-current-block) | [Get current parent](#get-current-parent) | [Callbacks](#callbacks)\n\n---\n\n### Get current block\nYou can get current block name:\n```Pug\n+b( 'nav' )\n    +e( 'item' )\n        - console.log( BEMPUG.getCurrentBlock() ); // 'nav'\n        +b( 'img' )\n            - console.log( BEMPUG.getCurrentBlock() ); // 'img'\n```\n\n---\n\n### Get current parent\nYou can get current parent `Object`:\n```Pug\n+b( 'html', 'no-js', 'html' )(lang='en')\n    - console.log( BEMPUG.getCurrentParent() );\n```\n```JS\n{ type: 'block',\n  name: 'html',\n  tag: 'html',\n  attributes: { lang: 'en' },\n  sep: { modifier: '--', element: '__' },\n  classes: [ 'html', 'html--no-js' ],\n  parent: {},\n  selfClosing: false }\n```\n\n---\n\n### Callbacks\nYou can set `beforeParse` callback:\n```Pug\n- BEMPUG.beforeParse[ 'input' ] = function( block ) {\n\n    if ( typeof block.data.m === 'undefined' ) block.data.m = 'default';\n}\n\n+b( 'input', {m: 'search'} ) // Have modifier 'search'\n\n+b( 'input' ) // No modifier, but we set modifier 'default' by callback\n```\n```HTML\n\u003cinput class=\"input input--search\"\u003e\n\u003cinput class=\"input input--default\"\u003e\n```\n\nYou can set `afterParse` callback:\n```Pug\n- BEMPUG.afterParse[ 'page' ] = function( block ) {\n\n    block.setTag( 'body' );\n    block.addModifier( 'test' );\n    block.attributes.itemscope = true;\n    block.attributes.itemtype = 'http://schema.org/WebPage';\n}\n\n+b( 'page' ) My page\n```\n```HTML\n\u003cbody class=\"page page--test\" itemscope itemtype=\"http://schema.org/WebPage\"\u003eMy page\u003c/body\u003e\n```\n\n---\n\n### Changelog\n\n#### 1.1.1\n* **Fixed**: disable parent mode not work in cb\n* **Fixed**: name of element in mix with another element\n\n#### 1.1.0\n* **Add**: ampersand sign for mix\n* **Add**: mix element with blocks and another elements\n\n#### 1.0.2\n* **Add**: some global helpers\n* **Add**: before / after parse callback\n* **Fixed**: block and element separators work for any descendant\n* **Fixed**: default tag depends on parent tag for any descendant\n\n#### 1.0.1\n* **Add**: disable parent mode for blocks\n\n#### 1.0.0\n* **Release version**\n\n---\n\n### Thanks\n\nMany thanks to Roman Komarov for the [original idea](https://github.com/kizu/bemto).\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fwerty1001%2Fbempug","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fwerty1001%2Fbempug","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fwerty1001%2Fbempug/lists"}