Getting Started Creating a static page
Lesson description
Creating a simple static page will help you understand the structure of a BEM project. This document describes the basics of working with BEM technology, redefinition levels, and BEM libraries.
You will learn how to:
Completing all the steps will result in a page with an input field, a button, and a user greeting, as shown in the figure below. The name entered in the field will be displayed in the greeting when the button is clicked.
Working with the examples laid out in this document requires basic skills in:
HTML
CSS
JavaScript
BEM
Important: This document does not contain information about the build procedure for a BEM project.
Minimum requirements
To begin, you will need to install:
Important: Windows OS users must install Git Bash.
We will be using
Template repository project-stub
Technologies:
Cloning a BEM project
To quickly deploy a BEM project, use a local copy of the project-stub template repository, which contains the minimum configuration files you'll need to get started. The main Bem libraries are connected to project-stub by default:
A copy of project-stub can be made using Git.
Please note: In OS X or Linux, all commands are executed in the terminal. Windows users must run commands in Git Bash. Make sure that Git Bash is launched from an administrator login.
To create a local copy of project-stub, do the following:
Clone project-stub into the
start-project
directory:git clone https://github.com/bem/project-stub.git --depth 1 start-project
Go to the project directory:
cd start-project
Set dependencies:
npm install
Please note: Do not use
root
superuser rights when setting npm-dependencies.Start the server using ENB:
npm start
By default, the server runs on port 8080.
Please note: If port
8080
is already being used by another program, you can reassign it:npm start -- -p 8081
Open your browser and enter the following address: http://localhost:8080/desktop.bundles/index/index.html. A page with sample blocks from the bem-components library should open.
After building and setting all dependencies, the project file structure will look like this:
start-project/ .bem .enb/ # Configuration files for ENB compiler common.blocks/ # Basic block implementations desktop.blocks/ # Project block directory desktop.bundles/ # Project bundle directories node_modules/ # Installed Node modules (packets) .bemrc # .editorconfig # EditorConfig configuration to support various editors and IDEs .gitignore # Exclusion of files and directories in Git .travis.yml # Automatic launch of linters in Continuous Integration favicon.ico # gulpfile.js # Configuration file for the Gulp compiler package.json # Project description for npm README.md # Text description of project
Creating a page
The desktop.bundles
project directory contains files obtained as a result of the build procedure. These files are called bundles in BEM. In the simplest instance, bundles are compiled for each page. In this case, one project page will correspond to one bundle directory. By default, the project has an index
page.
To add a new page:
Create a directory with the name of the page (for example,
hello
) indesktop. bundles
.Create the
hello.bemjson.js
file in thedesktop.bundles/hello/
directory.The root directory of the project will look like this:
start-project/ .bem .enb/ common.blocks/ desktop.blocks/ desktop.bundles/ index/ # index page bundle directory hello/ # hello page bundle directory hello.bemjson.js # hello page description
File and directory names follow the naming conventions.
Add a comment to file
hello.bemjson.js
in order to make sure that it isn't left empty:// BEMJSON description of the page will be here
Describing the page in a BEMJSON file
To create a page description, you'll need to define its structure. In this case, we're placing the hello
block on the page. It will contain a greeting (greeting
element of block hello
), a text box (input
block) and a button (button
block). The input and button blocks can be taken from the bem-components library.
More info about the BEMJSON input data format.
To define the page scructure, edit desktop.bundles/hello/hello.bemjson.js
:
Add the block
hello
.({ block : 'page', title : 'hello', head : [ { elem : 'css', url : 'hello.min.css' } ], scripts : [{ elem : 'js', url : 'hello.min.js' }], mods : { theme : 'islands' }, content : [ { block : 'hello' } ] })
Place the
greeting
element with the user welcome text (content
field) in thehello
block.content : [ { block : 'hello', content : [ { elem : 'greeting', content : 'Hello, %user%!' } ] } ]
Add the
input
andbutton
blocks to thehello
block.content : [ { block : 'hello', content : [ { elem : 'greeting', content : 'Hello, %user%!' }, { block : 'input', mods : { theme: 'islands', size : 'm' }, name : 'name', placeholder : 'User name' }, { block : 'button', mods : { theme : 'islands', size : 'm', type : 'submit' }, text : 'Click' } ] } ]
Full code of the BEMJSON file
To make sure that all the defined blocks and elements appear on the page, open the hello
page in your browser: http://localhost:8080/desktop.bundles/hello/hello.html.
Creating blocks
Blocks from the library have appeared on the page, but they do not interact with each other. We will now create the hello
block, which will take data from the input field and insert them it into the greeting. To do this:
Create a directory named
hello
indesktop. blocks
.Place the following block implementation files in it:
hello.js
— Defines the behavior of the block.hello.bemhtml.js
— Contains templates for generating the block's HTML markup.hello.css
— Contains the block styles.
Describing the block behavior
Open the file
desktop.blocks/hello/hello.js
.Insert the code that defines the block's reaction to user actions. When the button is clicked, the user name entered into the
input
field will be inserted into the greeting.JavaScript code is written using the i-bem.js declarative JavaScript framework.
// constructor for defining the reaction to an event onSetMod: { js: { inited: function() { this._input = this.findChildBlock(Input); } } }, _onSubmit: function(e) { // prevents triggering the default event: // sends the form to the server and refreshes the page e.preventDefault(); this._elem('greeting').domElem.text('Hello, ' + this._input.getVal() + '!'); }, { lazyInit: true, onInit: function() { // DOM event to react to this._domEvents().on('submit', this.prototype._onSubmit); } }
Use the YModules module system to present the given JavaScript code:
// adding dependencies from i-bem-dom, input and button modules.define('hello', ['i-bem-dom', 'input', 'button'], // the function that names of used modules are passed to function(provide, bemDom, Input, Button) { // declaration of the hello block provide(bemDom.declBlock('hello', { onSetMod: { js: { inited: function() { this._input = this.findChildBlock(Input); } } }, _onSubmit: function(e) { e.preventDefault(); this._elem('greeting').domElem.text('Hello, ' + this._input.getVal() + '!'); } }, { lazyInit: true, onInit: function() { this._domEvents().on('submit', this.prototype._onSubmit); } })); });
Creating the block template
BEMHTML is a technology that converts input data from a BEMJSON file into HTML.
To create a template:
Open the file
desktop.blocks/hello/hello.bemhtml.js
.Write a BEMHTML-template. In it, specify that the
hello
block uses a JavaScript implementation.Use the standard tag mode to wrap the
hello
block in a form.block('hello')( js()(true), tag()('form') );
Adding block styles
Edit
desktop.blocks/hello/hello.css
:.hello { color: green; padding: 10%; } .hello__greeting { margin-bottom: 12px; }
Create additional rules for the
input
element of thehello
block. They are needed in order to change theinput
block styles from the bem-components library..hello__input { margin-right: 12px; }
Use the mix field in
desktop.bundles/hello/hello.bemjson.js
to add additional CSS rules to theinput
block.{ block : 'input', mods : { theme : 'islands', size : 'm' }, // mix in element to add CSS rules mix : { block : 'hello', elem : 'input' }, name : 'name', placeholder : 'User name' }
See the Methodology section for more information about mixing.
Complete code of the desktop.bundles/hello/hello.bemjson.js
file.
Result
Refresh the page to check the results. A full rebuild of the project isn't necessary. A server mode that automatically rebuilds only the modified parts of the project was launched while the project was being developed.
Go to Creating a static project in BEM to see how to create a more complex static project.