Журнал LinuxFormat - перейти на главную

LXF168:Web-раз­ра­бот­ка. Django

Материал из Linuxformat
Перейти к: навигация, поиск

Кар­кас для web-при­ло­же­ний. Про­грам­ми­ро­вание в Django.

Содержание

Вве­де­ние в Django

Джо­но Бэ­кон при­ме­ня­ет Twitter Bootstrap для ук­ра­ше­ния про­ек­тов Django.

(thumbnail)
Наш эксперт Джо­но Бэ­кон управ­ля­ет со­об­ще­ст­вом Ubuntu; он ав­тор кни­ги «Ис­кус­ст­во со­об­ще­ст­ва» и ос­но­ва­тель еже­год­но­го сам­ми­та ру­ко­во­ди­те­лей со­об­ще­ст­ва.

Два уро­ка мы занима­лись соз­данием мощ­ных сай­тов с по­мо­щью по­пу­ляр­но­го фрейм­вор­ка Django. В пре­ды­ду­щих час­тях мы рас­смот­ре­ли та­кие те­мы, как соз­дание баз дан­ных, до­бав­ление дан­ных, ис­поль­зо­вание форм и дру­гие. Все это бы­ло очень... функ­цио­наль­но, но, к со­жа­лению, вы­гля­де­ло до­воль­но урод­ли­во.

На этом уро­ке мы уз­на­ем, как немно­го при­ук­ра­сить ва­ши при­ло­жения. Django до­би­ва­ет­ся мно­го­го ма­лым объ­е­мом ко­да. Мы соз­да­дим про­стую шаб­лон­ную про­грам­му и за­тем по­экс­пе­ри­мен­ти­ру­ем с на­бо­ром раз­лич­ных воз­мож­но­стей, чтобы соз­дать при­вле­ка­тель­ный сайт, со­вмес­ти­мый с боль­шин­ст­вом брау­зе­ров. При­сту­пим к де­лу.

Со­вре­мен­ная эпо­ха

Ска­жу для но­вич­ков в web-про­грам­ми­ро­вании: для соз­дания тем и сти­лей web-страниц ис­поль­зу­ет­ся спе­ци­аль­ный язык CSS (Cascading Style Sheets – кас­кад­ные таб­ли­цы сти­лей). С ним мож­но взять HTML-код страницы и из­менить ее ви­зу­аль­ное на­полнение, на­при­мер, цве­та и кон­ту­ры, а так­же рас­по­ло­жение тек­ста на странице. Увы, ве­те­ра­ны web-про­грам­ми­ро­вания хо­ро­шо зна­ют, что CSS чер­тов­ски сло­жен, не с точ­ки зрения язы­ка, а из-за всех этих уло­вок и прие­мов, тре­буе­мых для кор­рект­но­го ото­бра­жения со­дер­жи­мо­го страницы в раз­лич­ных брау­зе­рах, по­сколь­ку в ка­ж­дом из них то там, то здесь есть от­ли­чия. По су­ще­ст­ву, понимание CSS – это от­дель­ный на­вык, а на­пи­сание кра­си­во­го CSS – на­стоя­щее ис­кусст­во.

В былые вре­ме­на CSS для сай­тов при­хо­ди­лось пи­сать вруч­ную, и в итоге на­пло­ди­ли без­образ­ных сай­тов. К сча­стью, вре­ме­на из­менились, и хо­тя вруч­ную пи­сать никто не за­пре­ща­ет, боль­шин­ст­во лю­дей поль­зу­ют­ся кли­ент­ски­ми фрейм­вор­ка­ми, обо­ра­чи­ваю­щи­ми всю эту слож­ность в на­бор кир­пи­чи­ков «Ле­го» для с­борки ди­зайна страницы. Ина­че го­во­ря, вам доста­точ­но знать, как применять кир­пи­чи­ки, а они сде­ла­ют всю ра­бо­ту по ото­бра­жению долж­но­го CSS в лю­бом брау­зе­ре, ко­то­рым вы поль­зуе­тесь.

Су­ще­ст­ву­ет мас­са фрейм­вор­ков, ка­ж­дый со свои­ми досто­ин­ст­ва­ми и недостат­ка­ми. В качестве фрейм­вор­ка нам обыч­но нуж­но нечто гиб­кое (вклю­чаю­щее раз­но­об­раз­ные воз­мож­но­сти для раз­лич­ных тре­бо­ваний к ин­тер­фей­су поль­зо­ва­те­ля), при­ят­ное на вид (со­от­вет­ст­вую­щее вы­бран­но­му ва­ми ди­зай­ну), неболь­шое по раз­ме­ру (боль­шие страницы уве­ли­чи­ва­ют на­груз­ку на ка­нал) и ли­цен­зи­ро­ван­ное так, как вам нуж­но (в дан­ном слу­чае, доступ­ное сво­бод­но). Я ис­сле­до­вал мно­же­ст­во раз­лич­ных фрейм­вор­ков, и мне боль­ше всех прочих по­нра­вил­ся Bootstrap, соз­дан­ный в Twitter.

Bootstrap об­ла­да­ет фан­та­сти­че­­ским на­бо­ром воз­мож­но­стей. Он под­дер­жи­ва­ет раз­лич­ные гарниту­ры шриф­тов, ви­ды кно­пок, икон­ки, вклад­ки, мо­даль­ные диа­ло­ги, гиб­кие струк­ту­ры ком­понен­тов и дру­гое. Он при­ятен на вид, на­страи­ва­ем, снаб­жен пре­крас­ную до­ку­мен­та­цию и ли­цен­зи­ро­ван по сво­бод­ной ли­цен­зии Apache. К сча­стью, под­клю­чить его к Django про­сто, и это да­ет нам впе­чат­ляю­щие воз­мож­но­сти по из­менению внешнего ви­да сай­та.

Соз­да­ем шаб­лон

Начнем с соз­дания про­сто­го шаб­лон­но­го про­ек­та Django, и за­тем мы смо­жем по­смот­реть, как ра­бо­та­ют раз­лич­ные ком­понен­ты Bootstrap. Я про­бе­гусь по соз­данию про­ек­та до­воль­но бы­ст­ро, так как поч­ти все это долж­но быть вам зна­ко­мо.

Сна­ча­ла соз­да­ет­ся про­ект Django:

django-admin.py startproject homepage

За­тем за­да­дим на­строй­ки в settings.py. Спер­ва за­да­дим «шаб­лон­ный» по­иск про­ек­та в верхней час­ти фай­ла:

import os

ROOT_PROJECT = os.path.join(os.path.split(__file__)[0], “..”)

На­стро­им ба­зу дан­ных:

‘ENGINE’: ‘django.db.backends.sqlite3’

‘NAME’: ‘homepage.db’

В Django есть по­ня­тие ме­сто­по­ло­жения «ста­ти­че­­ских» фай­лов. Сю­да мы по­мес­тим фай­лы тем Bootstrap. По умол­чанию это ка­та­лог static про­ек­та. На­стро­им его – для это­го ука­жи­те сле­дую­щий па­ра­метр:

STATIC_URL = ‘/static/’

Свя­жем с этим ка­та­ло­гом па­ра­метр STATICFILES_DIRS:

STATICFILES_DIRS = (

os.path.join(ROOT_PROJECT, ‘static’),

)

Как и в пре­ды­ду­щих про­ек­тах, мы по­ме­ща­ем шаб­ло­ны в ка­та­лог ‘templates’ про­ек­та. За­дай­те сле­дую­щий па­ра­метр:

TEMPLATE_DIRS = (

“templates”,

)

Соз­да­дим в про­ек­те при­ло­же­ние mainapp:

python manage.py startapp mainapp

На­конец, до­бавь­те сле­дую­щие па­ра­мет­ры в раз­дел INSTALLED_APPS фай­ла settings.py. В на­шем при­ло­жении-шаб­лоне бу­дет три страницы: до­маш­няя, страница с ин­фор­ма­ци­ей о про­грам­ме и страница с кон­так­та­ми. В urls.py до­бавь­те сле­дую­щие па­ра­мет­ры:

url(r’^$’, ‘mainapp.views.index’),

url(r’^about/$’, ‘mainapp.views.about’),

url(r’^contact/$’, ‘mainapp.views.contact’),

Те­перь до­бавь­те пред­став­ле­ние в views.py:

from django.shortcuts import render

from mainapp.models import Contact

from mainapp.forms import ContactForm

from django.template import RequestContext

from django.shortcuts import render_to_response

def index(request):

return render(request, ‘mainapp/index.html’)

def about(request):

return render(request, ‘mainapp/about.html’)

def contact(request):

form = ContactForm(request.POST or None)

if form.is_valid():

cmodel = form.save()

cmodel.save()

return redirect(index)

return render_to_response(‘mainapp/contact.html’, {‘contact_form’: form}, context_instance=RequestContext(request))

Этот код про­сто вы­во­дит страницы – кро­ме страницы с кон­так­та­ми, на ко­то­рой вы­во­дит­ся фор­ма из мо­де­ли Contact data. До­ба­вим эту мо­дель в models.py:

class Contact(models.Model):

name = models.CharField(max_length=200)

email = models.CharField(max_length=200)

query = models.TextField(blank=True, null=True)

def __unicode__(self):

return self.name

По­том до­ба­вим файл forms.py для ото­бра­же­ния ModelForm:

from django.forms import ModelForm

from mainapp.models import Contact

class ContactForm(ModelForm):

class Meta:

model = Contact

За ис­клю­чением шаб­ло­нов (в ко­то­рые мы бу­дем до­бав­лять ин­фор­ма­цию о те­ме), наш шаб­лон­ный про­ект го­тов. Те­перь соз­да­дим ба­зу дан­ных:

python manage.py syncdb

(thumbnail)
> Рис. 1. На­ша рас­клад­ка по Bootstrap про­ста, но до­ход­чи­ва.

За­гру­зим и до­ба­вим в про­ект те­му Bootstrap. Для это­го сна­ча­ла соз­дай­те ка­та­лог static в корне про­ек­та. Зай­ди­те на http://twitter.github.com/bootstrap и за­гру­зи­те по­след­нюю вер­сию Bootstrap. В за­гру­жен­ном ар­хи­ве есть ка­та­лог bootstrap с тре­мя под­ка­та­ло­га­ми css, img и js. Рас­па­куй­те эти три под­ка­та­ло­га в свой ка­та­лог static. Те­перь все необ­хо­ди­мое для про­ек­та го­то­во, но мы по­ка не мо­жем его за­пустить, по­сколь­ку нет шаб­ло­нов. Ну так мы их до­ба­вим!

Те­мы и шаб­ло­ны

Что­бы восполь­зо­вать­ся Bootstrap, нуж­но до­ба­вить в шаб­ло­ны код, ко­то­рый за­гру­жа­ет биб­лио­те­ку bootstrap; по­сле это­го в шаб­лоне мож­но бу­дет поль­зо­вать­ся спе­ци­аль­ны­ми ко­ман­да­ми для ото­бра­жения со­дер­жи­мо­го раз­лич­ны­ми спо­со­ба­ми. Рань­ше у нас бы­ло по од­но­му шаб­ло­ну на страницу, и все бы­ло про­сто. Для на­ше­го се­го­дняшнего про­ек­та в шаб­ло­нах нуж­но за­гру­жать су­ще­ст­вую­щий код, фор­ми­рую­щий об­щую струк­ту­ру сай­та, а так­же код, за­гру­жаю­щий биб­лио­те­ку bootstrap.

На­стро­ить рас­по­ло­жение ком­понен­тов на странице с по­мо­щью Bootstrap мож­но по-раз­но­му, но для про­сто­ты мы ог­раничим­ся панелью на­ви­га­ции ввер­ху и дву­мя ко­лон­ка­ми на странице – основ­ным со­дер­жи­мым (col1) и бо­ко­вой ко­лон­кой (col2). Сна­ча­ла соз­да­дим ба­зо­вый файл шаб­ло­на, ко­то­рый бу­дут за­гру­жать все осталь­ные. В этом фай­ле мы за­гру­зим те­му Bootstrap и сфор­ми­ру­ем вы­ше­упо­мя­ну­тую схе­му из двух ко­ло­нок.

Хо­тя сей­час в на­шем про­ек­те Django все­го од­но при­ло­жение (mainapp), в бу­ду­щем их мо­жет стать несколь­ко, а мы хо­тим, что­бы в них во всех ис­поль­зо­ва­лась од­на и та же те­ма. Итак, соз­да­дим наш ба­зо­вый шаб­лон вне при­ло­жения mainapp, что­бы он мог со­вме­ст­но ис­поль­зо­вать­ся все­ми при­ло­жения­ми.

Для на­ча­ла соз­дай­те ка­та­лог templates в корневом ка­та­ло­ге про­ек­та, и в нем – файл base.html. Начнем до­бав­лять со­дер­жи­мое. Сна­ча­ла до­ба­вим несколь­ко ме­та-тэ­гов шаб­ло­на:

<!DOCTYPE html>

<html lang=”en”>

<head>

<meta charset=”utf-8”>

<title>My Homepage [Моя до­маш­няя стра­ни­ца]</title>

<meta name=”viewport” content=”width=devicewidth, initial-scale=1.0”>

<meta name=”description” content=””>

<meta name=”author” content=””>

За­тем за­гру­зим глав­ный CSS-файл Bootstrap. Он жи­вет в static/css, по­это­му восполь­зу­ем­ся спе­ци­аль­ным тэ­гом шаб­ло­на Django, что­бы со­слать­ся на ка­та­лог static:

<link href=”Шаблон:STATIC URL/css/bootstrap.css” rel=”stylesheet”>

Те­перь до­ба­вим дальней­шее со­дер­жи­мое – это несколь­ко бло­ков CSS, ко­то­рые вве­дут неболь­шие за­зо­ры ввер­ху и внизу страницы:

<style type=”text/css”>

body {

padding-top: 60px;

padding-bottom: 40px;

}

.sidebar-nav {

padding: 9px 0;

}

</style>

Да­лее до­ба­вим CSS-код Bootstrap, от­ве­чаю­щий за ди­зайн страницы. С ним страница бу­дет пра­виль­но ото­бра­жать­ся на план­ше­тах, те­ле­фо­нах и дру­гих уст­рой­ст­вах. Хо­тя на дан­ном уро­ке мы это­го не об­су­ж­да­ем, код все рав­но до­ба­вим, что­бы при же­лании об­ра­тить­ся к нему в бу­ду­щем:

<link href=”Шаблон:STATIC URL/css/bootstrapresponsive.css”rel=”stylesheet”>


<link rel=”shortcut icon” href=”../assets/ico/favicon.ico”>

<link rel=”apple-touch-icon-precomposed”sizes=”144x144” href=”../assets/ico/apple-touch-icon-144-precomposed.png”>

<link rel=”apple-touch-icon-precomposed”sizes=”114x114” href=”../assets/ico/apple-touch-icon-114-precomposed.png”>

<link rel=”apple-touch-icon-precomposed”sizes=”72x72” href=”../assets/ico/apple-touch-icon-72-precomposed.png”>

<link rel=”apple-touch-icon-precomposed”href=”../assets/ico/apple-touch-icon-57-precomposed.png”>

</head>

<body>

При­сту­пим к ор­ганиза­ции рас­клад­ки на­ше­го сай­та. Bootstrap пре­достав­ля­ет бо­га­тую кол­лек­цию клас­сов, при­ме­няе­мых к раз­лич­ным эле­мен­там HTML. На­при­мер, к тэ­гу ссыл­ки <a> мож­но при­менить класс, ко­то­рый пре­вра­тит ссыл­ку в кноп­ку ука­зан­ного ти­па. Ана­ло­гич­но, су­ще­ст­ву­ет на­бор клас­сов, при­ме­няе­мых к тэ­гу
для на­строй­ки рас­по­ло­жения ком­понен­тов страницы. Да­вай­те сна­ча­ла до­ба­вим панель на­ви­га­ции в верхней час­ти страницы.

<a class=”brand” href=”/”>My Homepage</a>

<a href=”” class=”btn btn-small btn-primary”>Sign In</a>

  • <a href=”/”>Home</a>
  • <a href=”/about”>About</a>
  • <a href=”/contact”>Contact</a>

В этом бло­ке мы спер­ва соз­да­ем внеш­нюю панель на­ви­га­ции (navbar), за­кре­п­лен­ную в верхней час­ти страницы (navbar-fixed-top), а за­тем до­бав­ля­ем ком­понен­ты к внут­ренней час­ти панели (navbar-inner). За­тем мы до­бав­ля­ем ссыл­ку с на­званием сай­та клас­са brand.

Да­лее до­бав­ля­ет­ся кноп­ка Sign In [Вой­ти] в ви­де ссыл­ки с клас­са­ми btn, btn-small и btn-primary. Это три раз­лич­ных клас­са; btn ото­бра­жа­ет ссыл­ку в ви­де кноп­ки, btn-small умень­ша­ет ее раз­мер, а btn-primary вы­де­ля­ет ее синим, как важ­ный эле­мент поль­зо­ва­тель­ско­го ин­тер­фей­са. Это хо­ро­ший при­мер фор­ма­ти­ро­вания страниц с Bootstrap.

На­конец, с по­мо­щью тэ­га nav мы до­бав­ля­ем мар­ки­ро­ван­ный спи­сок с тре­мя эле­мен­та­ми; они фор­ма­ти­ру­ют­ся как кноп­ки на­ви­га­ци­он­ной панели. Те­перь до­ба­вим код в те­ло страницы. Он соз­да­ет две ко­лон­ки:

{% block col1 %}

{% endblock %}

{% block col2 %}

{% endblock %}

Bootstrap де­лит страницу на 12 ко­ло­нок. Здесь мы соз­да­ем
для глав­ной ко­лон­ки и ис­поль­зу­ем в нем класс span9 – он забирает 9 из 12 ко­ло­нок. За­тем мы уста­нав­ли­ва­ем вто­рой
в span3 – это пре­вра­ща­ет три остав­ших­ся ко­лон­ки в уз­кую бо­ко­вую ко­лон­ку. Внут­ри ка­ж­до­го
оп­ре­де­ля­ем блок шаб­ло­на Django и за­даем его имя (col1 или col2). Име­на­ми мы восполь­зу­ем­ся в глав­ных шаб­ло­нах, что­бы до­бав­лять со­дер­жи­мое в эти ко­лон­ки. На­конец, до­ба­вим нижний ко­лон­ти­тул и фай­лы JavaScript (они до­бав­ля­ют­ся в кон­це фай­ла, что­бы страница за­гру­жа­лась бы­ст­рее):

<footer>

© Jono Bacon 2012

</footer>

<script src=”../assets/js/jquery.js”></script>

<script src=”../assets/js/bootstrap-transition.js”></script>

<script src=”../assets/js/bootstrap-alert.js”></script>

<script src=”../assets/js/bootstrap-modal.js”></script>

<script src=”../assets/js/bootstrap-dropdown.js”></script>

<script src=”../assets/js/bootstrap-scrollspy.js”></script>

<script src=”../assets/js/bootstrap-tab.js”></script>

<script src=”../assets/js/bootstrap-tooltip.js”></script>

<script src=”../assets/js/bootstrap-popover.js”></script>

<script src=”../assets/js/bootstrap-button.js”></script>

<script src=”../assets/js/bootstrap-collapse.js”></script>

<script src=”../assets/js/bootstrap-carousel.js”></script>

<script src=”../assets/js/bootstrap-typeahead.js”></script>

</body>

</html>

Наш ба­зо­вый шаб­лон го­тов; те­перь соз­да­дим шаб­лон страницы, что­бы про­ве­рить ди­зайн. Для это­го за­гру­зим шаб­ло­ны внут­ри при­ло­жения. Что­бы все шаб­ло­ны ис­поль­зо­ва­ли од­ну и ту же те­му, соз­дай­те ка­та­лог mainapp в ка­та­ло­ге templates и за­тем файл base.html в ка­та­ло­ге mainapp. До­бавь­те в него все­го од­ну стро­ку:

{% extends “base.html” %}

Она за­гру­жа­ет наш глав­ный файл base.html с ко­дом CSS, ко­то­рый при­ме­ня­ет­ся ко всем при­ло­жениям. Те­перь соз­да­дим шаб­лон страницы. В ка­та­ло­ге templates/mainapp соз­дай­те файл index.html и до­бавь­те в него сле­дую­щий код:

{% extends “mainapp/base.html” %}

{% block col1 %}

Welcome To My Homepage! [Доб­ро по­жа­ло­вать на мою до­маш­нюю стра­ни­цу!]

This is my very own homepage. Feel free to take a look around! [Я сам ее сде­лал. Смот­ри­те, не стес­няй­тесь!]

{% endblock %}

{% block col2 %}

{% endblock %}

В этом бло­ке мы за­гру­жа­ем ба­зо­вый шаб­лон и до­бав­ля­ем два бло­ка, ко­то­рые мы оп­ре­де­ли­ли в глав­ной струк­ту­ре. В пер­вом бло­ке (col1), то есть в те­ле страницы, мы про­сто до­бав­ля­ем за­го­ло­вок и немно­го тек­ста; вто­рой блок по­ка остав­ля­ем пустым. Те­перь страница долж­на вы­гля­деть так, как по­ка­за­но на рис. 1.

Соз­да­ем рас­клад­ку

Те­перь по­гру­зим­ся в воз­мож­но­сти Bootstrap, ко­то­рые при­да­ют ему та­кую мощь. Во-пер­вых, сей­час в бо­ко­вой ко­лон­ке ниче­го нет. До­ба­вим во вто­рой блок немно­го ин­фор­ма­ции о на­шей до­машней странице:

{% block col2 %}

The Technology

Этот сайт соз­дан при по­мо­щи Django и те­мы Bootstrap.

{% endblock %}

Здесь с по­мо­щью клас­са well эле­мен­та
мы соз­да­ем у бо­ко­вой ко­лон­ки тон­кий кон­тур с за­круг­лен­ны­ми края­ми. В том-то и пре­лесть Bootstrap – что­бы соз­дать кон­тур, не нуж­но пи­сать ника­ко­го ко­да CSS. Те­перь до­ба­вим несколь­ко кно­пок со ссыл­ка­ми на сай­ты Django и Bootstrap. Для это­го доста­точ­но до­ба­вить несколь­ко ссы­лок с клас­сом btn:

<a href=”https://www.djangoproject.com/”class=”btn”>Django</a>

<a href=”http://twitter.github.com/”class=”btn”>Bootstrap</a>

Ну вот, у нас есть кра­си­вые кноп­ки, вид ко­то­рых из­ме­ня­ет­ся при на­ве­дении кур­со­ра мы­ши. Су­ще­ст­ву­ют и дру­гие клас­сы, с по­мо­щью ко­то­рых мож­но ме­нять внешний вид кно­пок. На­при­мер, что­бы из­менить раз­мер кно­пок, восполь­зуй­тесь клас­са­ми btn-large, btn-small и btn-mini. Для это­го про­сто до­бавь­те их в код спра­ва от пер­во­го клас­са. На­при­мер:

<a href=”http://twitter.github.com/” class=”btn btnsmall”>Bootstrap</a>

Кноп­ки вы­гля­дят впол­не ми­ло, но луч­ше бу­дет объ­е­ди­нить их в груп­пу, на­при­мер, так:

<a href=”https://www.djangoproject.com/” class=”btn”>Django</a>

<a href=”http://twitter.github.com/” class=”btn”>Bootstrap</a>

Мы здесь восполь­зо­ва­лись клас­сом btn-group в тэ­ге
; те­перь кноп­ки сгруп­пи­ро­ва­ны.

Таб­ли­цы

Таб­ли­цы в Bootstrap то­же фор­ма­ти­ру­ют­ся про­сто. Те ужас­ные таб­ли­цы HTML, ко­то­рые вы зна­ли и лю­би­ли (нена­ви­де­ли), уш­ли в про­шлое. Вот при­мер таб­ли­цы с при­ят­ным кон­ту­ром, соз­дан­ным с по­мо­щью клас­са table-bordered:

NameAgeLocation
Steve Harris55London, England
Nicko McBrain52Florida, USA

Еще од­на при­ят­ная воз­мож­ность Bootstrap – на­бор ико­нок, ко­то­ры­ми мож­но бы­ст­ро и лег­ко восполь­зо­вать­ся. За­бы­ты дни, когда нуж­но бы­ло встраи­вать соб­ст­вен­ные икон­ки, что­бы при­дать при­вле­ка­тель­ность сай­ту.

С ка­ж­дой икон­кой свя­зан соб­ст­вен­ный класс. Да­вай­те до­ба­вим по икон­ке на ка­ж­дую из до­бав­лен­ных кно­пок:

<a href=”https://www.djangoproject.com/”class=”btn”> Django</a>

<a href=”http://twitter.github.com/” class=”btn”> Bootstrap</a>

Здесь мы до­ба­ви­ли пустой тэг и про­сто ука­за­ли класс для за­груз­ки нуж­ной икон­ки; при этом икон­ка бу­дет по­ка­за­на на ка­ж­дой кноп­ке с пра­виль­ны­ми от­сту­па­ми. Что­бы уви­деть пол­ный спи­сок доступ­ных ико­нок, зай­ди­те на до­маш­нюю страницу Bootstrap – http://twitter.github.com/.

Есть и пре­крас­ная до­ку­мен­та­ция. Бе­ри­тесь за де­ло и экс­пе­ри­мен­ти­руй­те с раз­лич­ны­ми воз­мож­но­стя­ми оформ­ления в соб­ст­вен­ных про­ек­тах. Уда­чи! |

Персональные инструменты
купить
подписаться
Яндекс.Метрика