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-projectdirectory:git clone https://github.com/bem/project-stub.git --depth 1 start-projectGo to the project directory:
cd start-projectSet dependencies:
npm install
Please note: Do not use
rootsuperuser rights when setting npm-dependencies.Start the server using ENB:
npm start
By default, the server runs on port 8080.
Please note: If port
8080is 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.jsfile 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 descriptionFile and directory names follow the naming conventions.
Add a comment to file
hello.bemjson.jsin 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
greetingelement with the user welcome text (contentfield) in thehelloblock.content : [ { block : 'hello', content : [ { elem : 'greeting', content : 'Hello, %user%!' } ] } ]Add the
inputandbuttonblocks to thehelloblock.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
helloindesktop. 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
inputfield 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
helloblock uses a JavaScript implementation.Use the standard tag mode to wrap the
helloblock 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
inputelement of thehelloblock. They are needed in order to change theinputblock styles from the bem-components library..hello__input { margin-right: 12px; }Use the mix field in
desktop.bundles/hello/hello.bemjson.jsto add additional CSS rules to theinputblock.{ 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.