mirror of
https://github.com/sinatra/sinatra
synced 2023-03-27 23:18:01 -04:00
improve and correct Russian README
Signed-off-by: Vasily Polovnyov <vast@whiteants.net> Signed-off-by: Konstantin Haase <konstantin.mailinglists@googlemail.com>
This commit is contained in:
parent
e3bc7f8e88
commit
256c5ad113
1 changed files with 76 additions and 76 deletions
152
README.ru.rdoc
152
README.ru.rdoc
|
@ -21,7 +21,7 @@ Sinatra — это предметно-ориентированный карка
|
|||
Результат можно увидеть: http://localhost:4567
|
||||
|
||||
Рекомендуется также установить thin, сделать это можно командой: <tt>gem install thin</tt>.
|
||||
Thin это более производительный и функциональный сервер для разработки приложений на Sinatra.
|
||||
Thin - это более производительный и функциональный сервер для разработки приложений на Sinatra.
|
||||
|
||||
== Маршруты
|
||||
|
||||
|
@ -52,7 +52,7 @@ Thin это более производительный и функционал
|
|||
.. что-то ответить ..
|
||||
end
|
||||
|
||||
Маршруты сверяются с запросом в порядке очередности их записи в файле приложения. Первый совпавший с запросом маршрут будет вызван.
|
||||
Маршруты сверяются с запросом в порядке очередности их записи в файле приложения. По умолчанию, будет вызван первый совпавший с запросом маршрут.
|
||||
|
||||
Шаблоны маршрутов могут включать в себя параметры доступные в
|
||||
<tt>params</tt> xэше:
|
||||
|
@ -135,17 +135,17 @@ Thin это более производительный и функционал
|
|||
=== Возвращаемые значения
|
||||
|
||||
Возвращаемое значение блока маршрута ограничивается телом ответа, которое будет передано HTTP клиенту,
|
||||
или следующей "прослойкой" (middleware, промежуточная программа) в Rack стеке. Чаще всего это строка, как в примерах выше.
|
||||
или следующей "прослойкой" (middleware) в Rack стеке. Чаще всего это строка, как в примерах выше.
|
||||
Но и другие значения также приемлемы.
|
||||
|
||||
Вы можете вернуть любой объект, который будет либо корректным Rack ответом, объектом Rack body, либо кодом состояния HTTP:
|
||||
|
||||
* Массив с тремя переменными: <tt>[status (Fixnum), headers (Hash), response body (должен отвечать на #each)]</tt>
|
||||
* Массив с двумя переменными: <tt>[status (Fixnum), response body (должен отвечать на #each)]</tt>
|
||||
* Объект, отвечающий на <tt>#each</tt>, который передает только строковые типы данных в этот блок
|
||||
* Fixnum, представляющий код состояния HTTP
|
||||
* массив с тремя переменными: <tt>[status (Fixnum), headers (Hash), response body (должен отвечать на #each)]</tt>;
|
||||
* массив с двумя переменными: <tt>[status (Fixnum), response body (должен отвечать на #each)]</tt>;
|
||||
* объект, отвечающий на <tt>#each</tt>, который передает только строковые типы данных в этот блок;
|
||||
* Fixnum, представляющий код состояния HTTP.
|
||||
|
||||
Таким образом мы легко можем создать поточный пример:
|
||||
Таким образом, мы легко можем создать поточный пример:
|
||||
|
||||
class Stream
|
||||
def each
|
||||
|
@ -195,10 +195,10 @@ Thin это более производительный и функционал
|
|||
# ...
|
||||
end
|
||||
|
||||
== статическые файлы
|
||||
== Статические файлы
|
||||
|
||||
статическые файлы отдаются из <tt>./public</tt> директории. Вы можете указать другое место,
|
||||
указав его в <tt>:public</tt> опции:
|
||||
Статические файлы отдаются из <tt>./public</tt> директории. Вы можете указать другое место,
|
||||
указав его через опцию <tt>:public</tt>:
|
||||
|
||||
set :public, File.dirname(__FILE__) + '/static'
|
||||
|
||||
|
@ -388,7 +388,7 @@ Thin это более производительный и функционал
|
|||
<tt>rdiscount</tt> gem/библиотека необходима для рендеринга Markdown шаблонов:
|
||||
|
||||
# Вам нужно будет подключить rdiscount в приложении
|
||||
require "rdiscount"
|
||||
require 'rdiscount'
|
||||
|
||||
get '/' do
|
||||
markdown :index
|
||||
|
@ -449,7 +449,7 @@ Thin это более производительный и функционал
|
|||
<tt>RedCloth</tt> gem/библиотека необходима для рендеринга Textile шаблонов:
|
||||
|
||||
# Вам нужно будет подключить redcloth в приложении
|
||||
require "redcloth"
|
||||
require 'redcloth'
|
||||
|
||||
get '/' do
|
||||
textile :index
|
||||
|
@ -494,7 +494,7 @@ Thin это более производительный и функционал
|
|||
<tt>rdoc</tt> gem/библиотека необходима для рендеринга RDoc шаблонов:
|
||||
|
||||
# Вам нужно будет подключить rdoc/markup/to_html в приложении
|
||||
require "rdoc/markup/to_html"
|
||||
require 'rdoc/markup/to_html'
|
||||
|
||||
get '/' do
|
||||
rdoc :index
|
||||
|
@ -589,13 +589,13 @@ Thin это более производительный и функционал
|
|||
Вам понадобится <tt>coffee-script</tt> gem/библиотека и что-то <b>одно</b> из следующего списка,
|
||||
чтобы запускать JavaScript:
|
||||
|
||||
* +node+ (из Node.js)
|
||||
* вы можете использовать OSX (есть встроенные средства для выполнения JavaScript)
|
||||
* +therubyracer+ gem/библиотека
|
||||
* +node+ (из Node.js);
|
||||
* вы можете использовать OS X (в которой есть встроенные средства для выполнения JavaScript);
|
||||
* +therubyracer+ gem/библиотека.
|
||||
|
||||
Подробнее смотрите на {странице проекта}[http://github.com/josh/ruby-coffee-script].
|
||||
|
||||
Таким образом вы можете использовать CoffeeScript шаблоны.
|
||||
Таким образом, вы можете использовать CoffeeScript шаблоны.
|
||||
|
||||
# Вам нужно будет подключить coffee-script gem в приложении
|
||||
require 'coffee-script'
|
||||
|
@ -612,7 +612,7 @@ Thin это более производительный и функционал
|
|||
haml '%div.title Hello World'
|
||||
end
|
||||
|
||||
Отобразит встроенный (строчный) шаблон.
|
||||
Отобразит строку встроенного шаблона.
|
||||
|
||||
=== Доступ к переменным в шаблонах
|
||||
|
||||
|
@ -631,7 +631,7 @@ Thin это более производительный и функционал
|
|||
haml '%h1= foo.name', :locals => { :foo => foo }
|
||||
end
|
||||
|
||||
Это обычный подход, когда шаблоны рендерятся как частные (partials) из других шаблонов.
|
||||
Это обычный подход, когда шаблоны рендерятся как части других шаблонов.
|
||||
|
||||
=== Вложенные шаблоны
|
||||
|
||||
|
@ -652,7 +652,7 @@ Thin это более производительный и функционал
|
|||
@@ index
|
||||
%div.title Hello world!!!!!
|
||||
|
||||
Заметьте: вложенные шаблоны, определенные в файле-исходнике, который подключил Sinatra, будут
|
||||
Заметьте: вложенные шаблоны, определенные в исходном файле, который подключила Sinatra, будут
|
||||
автоматически загружены. Вызовите <tt>enable :inline_templates</tt> напрямую, если у вас вложенные
|
||||
шаблоны в других файлах.
|
||||
|
||||
|
@ -672,8 +672,8 @@ Thin это более производительный и функционал
|
|||
haml :index
|
||||
end
|
||||
|
||||
Если шаблон с именем "layout" существует, то он будет использован каждый раз,
|
||||
когда шаблоны будут отрисовываться. Вы можете отключать лэйаут в каждом конкретном случае с помощью
|
||||
Если шаблон с именем "layout" существует, то он будет использоваться каждый раз
|
||||
при рендеринге. Вы можете отключать лэйаут (разметку) в каждом конкретном случае с помощью
|
||||
<tt>:layout => false</tt> или отключить его для всего приложения, например, так: <tt>set :haml, :layout => false</tt>:
|
||||
|
||||
get '/' do
|
||||
|
@ -682,7 +682,7 @@ Thin это более производительный и функционал
|
|||
|
||||
=== Привязка файловых расширений
|
||||
|
||||
Чтобы связать расширение файла и движок рендеринга, используйте
|
||||
Чтобы связать расширение файла с движком рендеринга, используйте
|
||||
<tt>Tilt.register</tt>. Например, если вы хотите использовать расширение +tt+
|
||||
для шаблонов Textile:
|
||||
|
||||
|
@ -782,7 +782,7 @@ Thin это более производительный и функционал
|
|||
end
|
||||
|
||||
Заметьте, что при использовании <tt>enable :sessions</tt> все данные
|
||||
сохраняются в куки. Это может быть не совсем то, что вы хотите (например,
|
||||
сохраняются в cookies. Это может быть не совсем то, что вы хотите (например,
|
||||
сохранение больших объемов данных увеличит ваш трафик). В таком случае вы
|
||||
можете использовать альтернативную Rack "прослойку" (middleware), реализующую
|
||||
механизм сессий. Для этого *не надо* вызывать <tt>enable :sessions</tt>,
|
||||
|
@ -908,7 +908,7 @@ Thin это более производительный и функционал
|
|||
Как и +body+, методы +headers+ и +status+, вызванные без аргументов, возвращают
|
||||
свои текущие значения.
|
||||
|
||||
=== Логгирование
|
||||
=== Логирование
|
||||
|
||||
В области видимости запроса метод +logger+ предоставляет доступ к экземпляру +Logger+:
|
||||
|
||||
|
@ -917,11 +917,11 @@ Thin это более производительный и функционал
|
|||
# ...
|
||||
end
|
||||
|
||||
Этот логгер автоматически учитывает ваши настройки логгирования в Rack. Если
|
||||
логгирование выключено, то этот метод вернет пустой (dummy) объект, поэтому вы можете
|
||||
Этот логер автоматически учитывает ваши настройки логирования в Rack. Если
|
||||
логирование выключено, то этот метод вернет пустой (dummy) объект, поэтому вы можете
|
||||
смело использовать его в маршрутах и фильтрах.
|
||||
|
||||
Заметьте, что логгирование включено по умолчанию только для <tt>Sinatra::Application</tt>,
|
||||
Заметьте, что логирование включено по умолчанию только для <tt>Sinatra::Application</tt>,
|
||||
а если ваше приложение -- подкласс <tt>Sinatra::Base</tt>, то вы, наверное, захотите включить
|
||||
его вручную:
|
||||
|
||||
|
@ -1022,9 +1022,9 @@ Thin это более производительный и функционал
|
|||
end
|
||||
|
||||
Чтобы как следует использовать кэши, вам следует подумать об использовании
|
||||
+etag+ и +last_modified+. Рекомендуется использовать эти методы *до*
|
||||
+etag+ и +last_modified+. Рекомендуется использовать эти методы-помощники *до*
|
||||
выполнения "тяжелых" вычислений, так как они немедленно отправят ответ клиенту,
|
||||
если текущая версия уже есть в его кэше:
|
||||
если текущая версия уже есть в их кэше:
|
||||
|
||||
get '/article/:id' do
|
||||
@article = Article.find params[:id]
|
||||
|
@ -1033,7 +1033,7 @@ Thin это более производительный и функционал
|
|||
erb :article
|
||||
end
|
||||
|
||||
Так же вы можете использовать
|
||||
Также вы можете использовать
|
||||
{weak ETag}[http://en.wikipedia.org/wiki/HTTP_ETag#Strong_and_weak_validation]:
|
||||
|
||||
etag @article.sha1, :weak
|
||||
|
@ -1042,8 +1042,8 @@ Thin это более производительный и функционал
|
|||
необходимую информацию для вашего кэша. Если вы ищите легкое решение для
|
||||
кэширования, попробуйте {rack-cache}[http://rtomayko.github.com/rack-cache/]:
|
||||
|
||||
require "rack/cache"
|
||||
require "sinatra"
|
||||
require 'rack/cache'
|
||||
require 'sinatra'
|
||||
|
||||
use Rack::Cache
|
||||
|
||||
|
@ -1192,8 +1192,8 @@ Thin это более производительный и функционал
|
|||
а вызывает заданный блок для всех возможных путей. Дело тут не в производительности,
|
||||
дело в том, что +render+ вызовет +break+, как только файл не будет найден.
|
||||
Содержимое и местонахождение шаблонов будет закэшировано, если приложение запущено не
|
||||
в режиме разработки. Вы должны помнить об этих нюансах, если пишите по-настоящему
|
||||
сумашедший метод.
|
||||
в режиме разработки (set :environment, :development). Вы должны помнить об этих нюансах,
|
||||
если пишите по-настоящему "сумашедший" метод.
|
||||
|
||||
== Конфигурация
|
||||
|
||||
|
@ -1274,7 +1274,7 @@ Thin это более производительный и функционал
|
|||
[environment] текущее окружение, по умолчанию, значение <tt>ENV['RACK_ENV']</tt>
|
||||
или <tt>"development"</tt>, если <tt>ENV['RACK_ENV']</tt> не доступна.
|
||||
|
||||
[logging] использовать логгер.
|
||||
[logging] использовать логер.
|
||||
|
||||
[lock] создает блокировку для каждого запроса, которая гарантирует обработку
|
||||
только одного запроса в текущий момент времени в Ruby процессе.
|
||||
|
@ -1290,7 +1290,7 @@ Thin это более производительный и функционал
|
|||
встроенным сервером.
|
||||
|
||||
[prefixed_redirects] добавлять или нет параметр <tt>request.script_name</tt> к редиректам,
|
||||
если не задан абсолютный путь. Таким образом <tt>redirect '/foo'</tt>
|
||||
если не задан абсолютный путь. Таким образом, <tt>redirect '/foo'</tt>
|
||||
будет вести себя как <tt>redirect to('/foo')</tt>. Отключено по умолчанию.
|
||||
|
||||
[public] директория, откуда будут раздаваться статические файлы.
|
||||
|
@ -1328,7 +1328,7 @@ Thin это более производительный и функционал
|
|||
Обработчики ошибок исполняются в том же контексте, что и маршруты, +before+-фильтры, а это означает, что всякие
|
||||
прелести вроде <tt>haml</tt>, <tt>erb</tt>, <tt>halt</tt> и т.д. доступны и им.
|
||||
|
||||
=== NotFound
|
||||
=== Not Found
|
||||
|
||||
Когда выброшено исключение <tt>Sinatra::NotFound</tt>, или кодом ответа является 404,
|
||||
то будет вызван <tt>not_found</tt> обработчик:
|
||||
|
@ -1411,7 +1411,7 @@ Rack::Builder[http://rack.rubyforge.org/doc/classes/Rack/Builder.html] DSL
|
|||
end
|
||||
|
||||
Rack распространяется с различными стандартными "прослойками"
|
||||
для логгирования, отладки, маршрутизации URL, аутентификации, обработки сессий. Sinatra использует
|
||||
для логирования, отладки, маршрутизации URL, аутентификации, обработки сессий. Sinatra использует
|
||||
многие из этих компонентов автоматически, основываясь на конфигурации, чтобы вам не приходилось
|
||||
подключать (+use+) их вручную.
|
||||
|
||||
|
@ -1454,9 +1454,9 @@ Rack распространяется с различными стандартн
|
|||
|
||||
Описание своего приложения самым простейшим способом (с помощью DSL верхнего уровня, как в примерах выше)
|
||||
работает отлично для крохотных приложений, но имеет множество недостатков, когда надо создать компоненты, такие как
|
||||
Rack middleware ("прослойки"), Rails metal, простые библиотеки с серверными компонентами,
|
||||
расширения Sinatra.
|
||||
DSL верхнего уровня загрязняет пространство имен <tt>Object</tt> и подразумевает стиль конфигурации
|
||||
Rack middleware ("прослойки"), Rails metal, простые библиотеки с серверными компонентами, расширения Sinatra.
|
||||
|
||||
DSL верхнего уровня "загрязняет" пространство имен <tt>Object</tt> и подразумевает стиль конфигурации
|
||||
микро-приложения (например, единый файл приложения, ./public и
|
||||
./views директории, создание логов, страницу деталей об исключениях
|
||||
и т.д.). И тут на помощь приходит Sinatra::Base:
|
||||
|
@ -1562,8 +1562,8 @@ Rack-совместимый сервер приложений.
|
|||
Вот несколько причин, по которым вы, возможно, захотите использовать <tt>config.ru</tt>:
|
||||
|
||||
* вы хотите разворачивать свое приложение на различных Rack-совместимых серверах (Passenger, Unicorn,
|
||||
Heroku, ...).
|
||||
* вы хотите использовать более одного подкласса <tt>Sinatra::Base</tt>.
|
||||
Heroku, ...);
|
||||
* вы хотите использовать более одного подкласса <tt>Sinatra::Base</tt>;
|
||||
* вы хотите использовать Sinatra только в качестве "прослойки" Rack.
|
||||
|
||||
<b>Совсем необязательно переходить на использование <tt>config.ru</tt> лишь потому, что вы стали
|
||||
|
@ -1573,7 +1573,7 @@ Rack-совместимый сервер приложений.
|
|||
=== Использование Sinatra в качестве "прослойки"
|
||||
|
||||
Не только сам Sinatra может использовать "прослойки" Rack, но и любое Sinatra приложение
|
||||
само может быть добавлено к любому Rack эндпоинту в качестве "прослойки". Этим эндпоинтом
|
||||
само может быть добавлено к любому Rack endpoint в качестве "прослойки". Этим endpoint (конечной точкой)
|
||||
может быть другое Sinatra приложение, или приложение, основанное на Rack (Rails/Ramaze/Camping/...):
|
||||
|
||||
require 'sinatra/base'
|
||||
|
@ -1633,15 +1633,15 @@ Sinatra::Application, иначе это будет подкласс, котор
|
|||
|
||||
У вас будет область видимости приложения внутри:
|
||||
|
||||
* Тела вашего класса приложения
|
||||
* Методов, определенных расширениями
|
||||
* Блока, переданного в +helpers+
|
||||
* Блоков, использованных как значения для +set+
|
||||
* тела вашего класса приложения;
|
||||
* методов, определенных расширениями;
|
||||
* блока, переданного в +helpers+;
|
||||
* блоков, использованных как значения для +set+.
|
||||
|
||||
Вы можете получить доступ к объекту области видимости (классу приложения) следующими способами:
|
||||
|
||||
* объект, переданный блокам конфигурации (<tt>configure { |c| ... }</tt>)
|
||||
* +settings+ внутри области видимости запроса
|
||||
* через объект, переданный блокам конфигурации (<tt>configure { |c| ... }</tt>);
|
||||
* +settings+ внутри области видимости запроса.
|
||||
|
||||
=== Область видимости запроса/экземпляра
|
||||
|
||||
|
@ -1649,7 +1649,7 @@ Sinatra::Application, иначе это будет подкласс, котор
|
|||
и все блоки обработчика будут запущены в этом контексте. В этой области
|
||||
видимости вам доступны +request+ и +session+ объекты, вызовы методов
|
||||
рендеринга, такие как +erb+ или +haml+. Вы можете получить доступ к
|
||||
области видимости приложения из контекста запроса, используя помощник +settings+:
|
||||
области видимости приложения из контекста запроса, используя метод-помощник +settings+:
|
||||
|
||||
class MyApp < Sinatra::Base
|
||||
# Я в области видимости приложения!
|
||||
|
@ -1668,10 +1668,10 @@ Sinatra::Application, иначе это будет подкласс, котор
|
|||
|
||||
У вас будет область видимости запроса внутри:
|
||||
|
||||
* get/head/post/put/delete/options блоков
|
||||
* before/after фильтрах
|
||||
* методах-помощниках
|
||||
* шаблонах/отображениях
|
||||
* get/head/post/put/delete/options блоков;
|
||||
* before/after фильтрах;
|
||||
* методах-помощниках;
|
||||
* шаблонах/отображениях.
|
||||
|
||||
=== Область видимости делегирования
|
||||
|
||||
|
@ -1685,8 +1685,8 @@ Sinatra::Application, иначе это будет подкласс, котор
|
|||
|
||||
У вас будет контекст делегирования внутри:
|
||||
|
||||
* Привязки верхнего уровня, если вы сделали <tt>require "sinatra"</tt>
|
||||
* Объекта, расширенного с помощью <tt>Sinatra::Delegator</tt>
|
||||
* привязки верхнего уровня, если вы сделали <tt>require 'sinatra'</tt>;
|
||||
* объекта, расширенного с помощью <tt>Sinatra::Delegator</tt>.
|
||||
|
||||
Посмотрите сами в код: тут
|
||||
{Sinatra::Delegator примесь}[http://github.com/sinatra/sinatra/blob/ceac46f0bc129a6e994a06100aa854f606fe5992/lib/sinatra/base.rb#L1128]
|
||||
|
@ -1700,11 +1700,11 @@ Sinatra приложения могут быть запущены напряму
|
|||
|
||||
Опции включают:
|
||||
|
||||
-h # помощь
|
||||
-p # указать порт (по умолчанию 4567)
|
||||
-o # указать хост (по умолчанию 0.0.0.0)
|
||||
-e # указать окружение, режим (по умолчанию development)
|
||||
-s # указать rack сервер/обработчик (по умолчанию thin)
|
||||
-h # раздел помощи
|
||||
-p # указание порта (по умолчанию 4567)
|
||||
-o # указание хоста (по умолчанию 0.0.0.0)
|
||||
-e # указание окружения, режима (по умолчанию development)
|
||||
-s # указание rack сервера/обработчика (по умолчанию thin)
|
||||
-x # включить мьютекс-блокировку (по умолчанию выключена)
|
||||
|
||||
== Системные требования
|
||||
|
@ -1721,7 +1721,7 @@ Sinatra приложения могут быть запущены напряму
|
|||
версия весьма не стабильна при использовании Sinatra.
|
||||
|
||||
[ Rubinius ]
|
||||
Rubinius официально поддерживается (Rubinius >= 1.2.3), все, включая все
|
||||
Rubinius официально поддерживается (Rubinius >= 1.2.3), всё, включая все
|
||||
языки шаблонов, работает.
|
||||
|
||||
[ JRuby ]
|
||||
|
@ -1733,15 +1733,15 @@ Sinatra приложения могут быть запущены напряму
|
|||
|
||||
<b>Ruby 1.8.6 больше не поддерживается.</b>
|
||||
|
||||
Мы также следим за предстоящими версиями Ruby.
|
||||
Мы также следим за предстоящими к выходу версиями Ruby.
|
||||
|
||||
Следующие реализации Ruby не поддерживаются официально, но известно, что на
|
||||
них запускается Sinatra:
|
||||
|
||||
* Старые версии JRuby и Rubinius
|
||||
* MacRuby, Maglev, IronRuby
|
||||
* Ruby 1.9.0 и 1.9.1
|
||||
* Ruby 1.8.6 с помощью {backports}[https://github.com/marcandre/backports/#readme]
|
||||
* старые версии JRuby и Rubinius;
|
||||
* MacRuby, Maglev, IronRuby;
|
||||
* Ruby 1.9.0 и 1.9.1;
|
||||
* Ruby 1.8.6 с помощью {backports}[https://github.com/marcandre/backports/#readme].
|
||||
|
||||
То, что версия официально не поддерживается, означает, что, если что-то не
|
||||
работает на этой версии, а на поддерживаемой работает - это не наша проблема, а их.
|
||||
|
@ -1761,7 +1761,7 @@ Sinatra должна работать на любой операционной
|
|||
|
||||
gem install sinatra --pre
|
||||
|
||||
Чтобы воспользоваться некоторыми самыми последними возможностям.
|
||||
Чтобы воспользоваться некоторыми самыми последними возможностями.
|
||||
|
||||
=== С помощью Bundler
|
||||
|
||||
|
@ -1823,10 +1823,10 @@ SemVerTag.
|
|||
|
||||
== Дальнейшее чтение
|
||||
|
||||
* {Вебсайт проекта}[http://www.sinatrarb.com/] - Дополнительная документация,
|
||||
* {Веб-сайт проекта}[http://www.sinatrarb.com/] - Дополнительная документация,
|
||||
новости и ссылки на другие ресурсы.
|
||||
* {Участие}[http://www.sinatrarb.com/contributing] - Обнаружили баг? Нужна помощь? Написали патч?
|
||||
* {Слежение за проблемами}[http://github.com/sinatra/sinatra/issues]
|
||||
* {Участие в проекте}[http://www.sinatrarb.com/contributing] - Обнаружили баг? Нужна помощь? Написали патч?
|
||||
* {Слежение за проблемами/ошибками}[http://github.com/sinatra/sinatra/issues]
|
||||
* {Twitter}[http://twitter.com/sinatra]
|
||||
* {Лист рассылки}[http://groups.google.com/group/sinatrarb/topics]
|
||||
* {IRC: #sinatra}[irc://chat.freenode.net/#sinatra] on http://freenode.net
|
||||
* {Группы рассылки}[http://groups.google.com/group/sinatrarb/topics]
|
||||
* {IRC: #sinatra}[irc://chat.freenode.net/#sinatra] on http://freenode.net
|
||||
|
|
Loading…
Add table
Reference in a new issue