Introducing jekyll (jekyllrb.com) for docs
parent
9957e18d31
commit
b24582aead
@ -1,3 +1,4 @@
|
||||
scripts/gen
|
||||
templating/out
|
||||
*.pyc
|
||||
supporting-docs/_site
|
||||
|
@ -0,0 +1,15 @@
|
||||
# Site settings
|
||||
title: Matrix
|
||||
email: webmaster@matrix.org
|
||||
description: > # this means to ignore newlines until "baseurl:"
|
||||
Matrix.org documentation
|
||||
baseurl: "/docs/guides" # the subpath of your site, e.g. /blog/
|
||||
url: "http://matrix.org" # the base hostname & protocol for your site
|
||||
twitter_username: matrixdotorg
|
||||
github_username: matrix-org
|
||||
|
||||
# Build settings
|
||||
markdown: kramdown
|
||||
|
||||
#defaults:
|
||||
permalink: /:categories/:title.html
|
@ -0,0 +1 @@
|
||||
<div id="footer"><div id="footerContent">© 2014-2015 Matrix.org</div>
|
@ -0,0 +1,14 @@
|
||||
<meta charset="utf-8">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
|
||||
<title>{% if page.title %}{{ page.title }}{% else %}{{ site.title }}{% endif %}</title>
|
||||
<meta name="description" content="{% if page.excerpt %}{{ page.excerpt | strip_html | strip_newlines | truncate: 160 }}{% else %}{{ site.description }}{% endif %}">
|
||||
|
||||
<link rel="stylesheet" href="{{ "/css/main.css" | prepend: site.baseurl }}">
|
||||
<link rel="stylesheet" href="{{ "/css/site.css" | prepend: site.baseurl }}">
|
||||
<link rel="stylesheet" href="{{ "/css/basic.css" | prepend: site.baseurl }}">
|
||||
<link rel="stylesheet" href="{{ "/css/nature.css" | prepend: site.baseurl }}">
|
||||
|
||||
<link rel="canonical" href="{{ page.url | replace:'index.html','' | prepend: site.baseurl | prepend: site.url }}">
|
||||
<link rel="alternate" type="application/rss+xml" title="{{ site.title }}" href="{{ "/feed.xml" | prepend: site.baseurl | prepend: site.url }}" />
|
@ -0,0 +1,22 @@
|
||||
<div id="header">
|
||||
<div id="headerContent">
|
||||
|
||||
<a href="/#about2" class="navButton">About</a>
|
||||
<a href="/docs/howtos" class="navButton">HOWTOs</a>
|
||||
<a href="/docs/spec" class="navButton">Spec</a>
|
||||
<a href="/docs/api" class="navButton">APIs</a>
|
||||
<a href="/code" class="navButton">Code</a>
|
||||
<a href="/jira" class="navButton">JIRA</a>
|
||||
<a href="/blog/faq" class="navButton">FAQ</a>
|
||||
<a href="/blog" class="navButton">Blog</a>
|
||||
<script>
|
||||
(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
|
||||
(i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
|
||||
m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
|
||||
})(window,document,'script','//www.google-analytics.com/analytics.js','ga');
|
||||
|
||||
ga('create', 'UA-54779209-1', 'auto');
|
||||
ga('send', 'pageview');
|
||||
</script>
|
||||
</div>
|
||||
</div>
|
@ -0,0 +1,19 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
{% include head.html %}
|
||||
|
||||
</head>
|
||||
<body>
|
||||
{% include nav.html %}
|
||||
<br />
|
||||
<div class="page-content">
|
||||
<div class="wrapper">
|
||||
{{ content }}
|
||||
</div>
|
||||
</div>
|
||||
{% include footer.html %}
|
||||
|
||||
</body>
|
||||
|
||||
</html>
|
@ -0,0 +1,14 @@
|
||||
---
|
||||
layout: default
|
||||
---
|
||||
<div class="post">
|
||||
|
||||
<header class="post-header">
|
||||
<h1 class="post-title">{{ page.title }}</h1>
|
||||
</header>
|
||||
|
||||
<article class="post-content">
|
||||
{{ content }}
|
||||
</article>
|
||||
|
||||
</div>
|
@ -0,0 +1,6 @@
|
||||
---
|
||||
layout: default
|
||||
---
|
||||
|
||||
{{ content }}
|
||||
|
@ -0,0 +1 @@
|
||||
*.pyc
|
@ -0,0 +1,20 @@
|
||||
The MIT License (MIT)
|
||||
Copyright (c) 2011 Greg Thornton, http://xdissent.com
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
@ -0,0 +1,97 @@
|
||||
Overview
|
||||
========
|
||||
|
||||
This plugin adds `ReStructuredText`_ support to `Jekyll`_ and `Octopress`_.
|
||||
It renders ReST in posts and pages, and provides a custom directive to
|
||||
support Octopress-compatible syntax highlighting.
|
||||
|
||||
Requirements
|
||||
============
|
||||
|
||||
* Jekyll *or* Octopress >= 2.0
|
||||
* Docutils
|
||||
* Pygments
|
||||
* `RbST`_
|
||||
|
||||
Installation
|
||||
============
|
||||
|
||||
1. Install Docutils and Pygments.
|
||||
|
||||
The most convenient way is to use virtualenv_burrito:
|
||||
|
||||
::
|
||||
|
||||
$ curl -s https://raw.github.com/brainsik/virtualenv-burrito/master/virtualenv-burrito.sh | bash
|
||||
$ source /Users/xdissent/.venvburrito/startup.sh
|
||||
$ mkvirtualenv jekyll-rst
|
||||
$ pip install docutils pygments
|
||||
|
||||
2. Install RbST.
|
||||
|
||||
If you use `bundler`_ with Octopress, add ``gem 'RbST'`` to
|
||||
your ``Gemfile`` in the ``development`` group, then run
|
||||
``bundle install``. Otherwise, ``gem install RbST``.
|
||||
|
||||
3. Install the plugin.
|
||||
|
||||
For Jekyll:
|
||||
|
||||
::
|
||||
|
||||
$ cd <jekyll-project-path>
|
||||
$ git submodule add https://github.com/xdissent/jekyll-rst.git _plugins/jekyll-rst
|
||||
|
||||
For Octopress:
|
||||
|
||||
::
|
||||
|
||||
$ cd <octopress-project-path>
|
||||
$ git submodule add https://github.com/xdissent/jekyll-rst.git plugins/jekyll-rst
|
||||
|
||||
4. Start blogging in ReStructuredText. Any file with the ``.rst`` extension
|
||||
will be parsed as ReST and rendered into HTML.
|
||||
|
||||
.. note:: Be sure to activate the ``jekyll-rst`` virtualenv before generating
|
||||
the site by issuing a ``workon jekyll-rst``. I suggest you follow `Harry
|
||||
Marr's advice`_ and create a ``.venv`` file that will automatically
|
||||
activate the ``jekyll-rst`` virtualenv when you ``cd`` into your project.
|
||||
|
||||
Source Code Highlighting
|
||||
========================
|
||||
|
||||
A ``code-block`` ReST directive is registered and aliased as ``sourcecode``.
|
||||
It adds syntax highlighting to code blocks in your documents::
|
||||
|
||||
.. code-block:: ruby
|
||||
|
||||
# Output "I love ReST"
|
||||
say = "I love ReST"
|
||||
puts say
|
||||
|
||||
Optional arguments exist to supply a caption, link, and link title::
|
||||
|
||||
.. code-block:: console
|
||||
:caption: Read Hacker News on a budget
|
||||
:url: http://news.ycombinator.com
|
||||
:title: Hacker News
|
||||
|
||||
$ curl http://news.ycombinator.com | less
|
||||
|
||||
Octopress already includes style sheets for syntax highlighting, but you'll
|
||||
need to generate one yourself if using Jekyll::
|
||||
|
||||
$ pygmentize -S default -f html > css/pygments.css
|
||||
|
||||
Octopress Tips
|
||||
==============
|
||||
|
||||
* Use ``.. more`` in your ReST documents to indicate where Octopress's
|
||||
``excerpt`` tag should split your content for summary views.
|
||||
|
||||
.. _ReStructuredText: http://docutils.sourceforge.net/rst.html
|
||||
.. _Jekyll: http://jekyllrb.com/
|
||||
.. _Octopress: http://octopress.com/
|
||||
.. _RbST: http://rubygems.org/gems/RbST
|
||||
.. _bundler: http://gembundler.com/
|
||||
.. _Harry Marr's advice: http://hmarr.com/2010/jan/19/making-virtualenv-play-nice-with-git/
|
@ -0,0 +1,30 @@
|
||||
require 'rbst'
|
||||
|
||||
module Jekyll
|
||||
class RestConverter < Converter
|
||||
safe true
|
||||
|
||||
priority :low
|
||||
|
||||
def matches(ext)
|
||||
ext =~ /rst/i
|
||||
end
|
||||
|
||||
def output_ext(ext)
|
||||
".html"
|
||||
end
|
||||
|
||||
def convert(content)
|
||||
RbST.executables = {:html => "#{File.expand_path(File.dirname(__FILE__))}/rst2html.py"}
|
||||
RbST.new(content).to_html(:part => :fragment, :initial_header_level => 2)
|
||||
end
|
||||
end
|
||||
|
||||
module Filters
|
||||
def restify(input)
|
||||
site = @context.registers[:site]
|
||||
converter = site.getConverterImpl(Jekyll::RestConverter)
|
||||
converter.convert(input)
|
||||
end
|
||||
end
|
||||
end
|
@ -0,0 +1,97 @@
|
||||
# Define a new directive `code-block` (aliased as `sourcecode`) that uses the
|
||||
# `pygments` source highlighter to render code in color.
|
||||
#
|
||||
# Incorporates code from the `Pygments`_ documentation for `Using Pygments in
|
||||
# ReST documents`_ and `Octopress`_.
|
||||
#
|
||||
# .. _Pygments: http://pygments.org/
|
||||
# .. _Using Pygments in ReST documents: http://pygments.org/docs/rstdirective/
|
||||
# .. _Octopress: http://octopress.org/
|
||||
|
||||
import re
|
||||
import os
|
||||
import md5
|
||||
import __main__
|
||||
|
||||
# Absolute path to pygments cache dir
|
||||
PYGMENTS_CACHE_DIR = os.path.abspath(os.path.join(os.path.dirname(__main__.__file__), '../../.pygments-cache'))
|
||||
|
||||
# Ensure cache dir exists
|
||||
if not os.path.exists(PYGMENTS_CACHE_DIR):
|
||||
os.makedirs(PYGMENTS_CACHE_DIR)
|
||||
|
||||
from pygments.formatters import HtmlFormatter
|
||||
|
||||
from docutils import nodes
|
||||
from docutils.parsers.rst import directives, Directive
|
||||
|
||||
from pygments import highlight
|
||||
from pygments.lexers import get_lexer_by_name, TextLexer
|
||||
|
||||
class Pygments(Directive):
|
||||
""" Source code syntax hightlighting.
|
||||
"""
|
||||
required_arguments = 1
|
||||
optional_arguments = 0
|
||||
final_argument_whitespace = True
|
||||
string_opts = ['title', 'url', 'caption']
|
||||
option_spec = dict([(key, directives.unchanged) for key in string_opts])
|
||||
has_content = True
|
||||
|
||||
def run(self):
|
||||
self.assert_has_content()
|
||||
try:
|
||||
lexer_name = self.arguments[0]
|
||||
lexer = get_lexer_by_name(lexer_name)
|
||||
except ValueError:
|
||||
# no lexer found - use the text one instead of an exception
|
||||
lexer_name = 'text'
|
||||
lexer = TextLexer()
|
||||
formatter = HtmlFormatter()
|
||||
|
||||
# Construct cache filename
|
||||
cache_file = None
|
||||
content_text = u'\n'.join(self.content)
|
||||
cache_file_name = '%s-%s.html' % (lexer_name, md5.new(content_text).hexdigest())
|
||||
cached_path = os.path.join(PYGMENTS_CACHE_DIR, cache_file_name)
|
||||
|
||||
# Look for cached version, otherwise parse
|
||||
if os.path.exists(cached_path):
|
||||
cache_file = open(cached_path, 'r')
|
||||
parsed = cache_file.read()
|
||||
else:
|
||||
parsed = highlight(content_text, lexer, formatter)
|
||||
|
||||
# Strip pre tag and everything outside it
|
||||
pres = re.compile("<pre>(.+)<\/pre>", re.S)
|
||||
stripped = pres.search(parsed).group(1)
|
||||
|
||||
# Create tabular code with line numbers
|
||||
table = '<div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers">'
|
||||
lined = ''
|
||||
for idx, line in enumerate(stripped.splitlines(True)):
|
||||
table += '<span class="line-number">%d</span>\n' % (idx + 1)
|
||||
lined += '<span class="line">%s</span>' % line
|
||||
table += '</pre></td><td class="code"><pre><code class="%s">%s</code></pre></td></tr></table></div>' % (lexer_name, lined)
|
||||
|
||||
# Add wrapper with optional caption and link
|
||||
code = '<figure class="code">'
|
||||
if self.options:
|
||||
caption = ('<span>%s</span>' % self.options['caption']) if 'caption' in self.options else ''
|
||||
title = self.options['title'] if 'title' in self.options else 'link'
|
||||
link = ('<a href="%s">%s</a>' % (self.options['url'], title)) if 'url' in self.options else ''
|
||||
|
||||
if caption or link:
|
||||
code += '<figcaption>%s %s</figcaption>' % (caption, link)
|
||||
code += '%s</figure>' % table
|
||||
|
||||
# Write cache
|
||||
if cache_file is None:
|
||||
cache_file = open(cached_path, 'w')
|
||||
cache_file.write(parsed)
|
||||
cache_file.close()
|
||||
|
||||
return [nodes.raw('', code, format='html')]
|
||||
|
||||
directives.register_directive('code-block', Pygments)
|
||||
directives.register_directive('sourcecode', Pygments)
|
@ -0,0 +1,39 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
# :Author: David Goodger, the Pygments team, Guenter Milde
|
||||
# :Date: $Date: $
|
||||
# :Copyright: This module has been placed in the public domain.
|
||||
|
||||
# This is a merge of the `Docutils`_ `rst2html` front end with an extension
|
||||
# suggestion taken from the `Pygments`_ documentation, reworked specifically
|
||||
# for `Octopress`_.
|
||||
#
|
||||
# .. _Pygments: http://pygments.org/
|
||||
# .. _Docutils: http://docutils.sourceforge.net/
|
||||
# .. _Octopress: http://octopress.org/
|
||||
|
||||
"""
|
||||
A front end to docutils, producing HTML with syntax colouring using pygments
|
||||
"""
|
||||
|
||||
try:
|
||||
import locale
|
||||
locale.setlocale(locale.LC_ALL, '')
|
||||
except:
|
||||
pass
|
||||
|
||||
from transform import transform
|
||||
from docutils.writers.html4css1 import Writer
|
||||
from docutils.core import default_description
|
||||
from directives import Pygments
|
||||
|
||||
description = ('Generates (X)HTML documents from standalone reStructuredText '
|
||||
'sources. Uses `pygments` to colorize the content of'
|
||||
'"code-block" directives. Needs an adapted stylesheet'
|
||||
+ default_description)
|
||||
|
||||
def main():
|
||||
return transform(writer=Writer(), part='html_body')
|
||||
|
||||
if __name__ == '__main__':
|
||||
print(main())
|
@ -0,0 +1,42 @@
|
||||
import sys
|
||||
from docutils.core import publish_parts
|
||||
from optparse import OptionParser
|
||||
from docutils.frontend import OptionParser as DocutilsOptionParser
|
||||
from docutils.parsers.rst import Parser
|
||||
|
||||
def transform(writer=None, part=None):
|
||||
p = OptionParser(add_help_option=False)
|
||||
|
||||
# Collect all the command line options
|
||||
docutils_parser = DocutilsOptionParser(components=(writer, Parser()))
|
||||
for group in docutils_parser.option_groups:
|
||||
p.add_option_group(group.title, None).add_options(group.option_list)
|
||||
|
||||
p.add_option('--part', default=part)
|
||||
|
||||
opts, args = p.parse_args()
|
||||
|
||||
settings = dict({
|
||||
'file_insertion_enabled': False,
|
||||
'raw_enabled': False,
|
||||
'doctitle_xform': False,
|
||||
})
|
||||
|
||||
if len(args) == 1:
|
||||
try:
|
||||
content = open(args[0], 'r').read()
|
||||
except IOError:
|
||||
content = args[0]
|
||||
else:
|
||||
content = sys.stdin.read()
|
||||
|
||||
parts = publish_parts(
|
||||
source=content,
|
||||
writer=writer,
|
||||
settings_overrides=settings
|
||||
)
|
||||
if 'html_body' in parts:
|
||||
return parts['html_body']
|
||||
if opts.part in parts:
|
||||
return parts[opts.part]
|
||||
return ''
|
@ -0,0 +1,51 @@
|
||||
module Jekyll
|
||||
class ProjectVersionTag < Liquid::Tag
|
||||
NO_GIT_MESSAGE = 'Oops, are you sure this is a git project?'
|
||||
UNABLE_TO_PARSE_MESSAGE = 'Sorry, could not read project version at the moment'
|
||||
|
||||
def render(context)
|
||||
if git_repo?
|
||||
current_version.chomp
|
||||
else
|
||||
NO_GIT_MESSAGE
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def current_version
|
||||
@_current_version ||= begin
|
||||
# attempt to find the latest tag, falling back to last commit
|
||||
version = git_describe || parse_head
|
||||
|
||||
version || UNABLE_TO_PARSE_MESSAGE
|
||||
end
|
||||
end
|
||||
|
||||
def git_describe
|
||||
tagged_version = %x{ git describe --tags --always }
|
||||
|
||||
if command_succeeded?
|
||||
tagged_version
|
||||
end
|
||||
end
|
||||
|
||||
def parse_head
|
||||
head_commitish = %x{ git rev-parse --short HEAD }
|
||||
|
||||
if command_succeeded?
|
||||
head_commitish
|
||||
end
|
||||
end
|
||||
|
||||
def command_succeeded?
|
||||
!$?.nil? && $?.success?
|
||||
end
|
||||
|
||||
def git_repo?
|
||||
system('git rev-parse')
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
Liquid::Template.register_tag('project_version', Jekyll::ProjectVersionTag)
|
@ -0,0 +1,652 @@
|
||||
---
|
||||
layout: post
|
||||
title: Client-Server API
|
||||
categories: guides
|
||||
---
|
||||
|
|
||||
|
||||
.. figure:: http://matrix.org/matrix.png
|
||||
:width: 305px
|
||||
:height: 130px
|
||||
:alt: [matrix]
|
||||
:align: center
|
||||
|
||||
|
||||
How to use the client-server API
|
||||
================================
|
||||
|
||||
.. NOTE::
|
||||
The git version of this document is {% project_version %}
|
||||
|
||||
This guide focuses on how the client-server APIs *provided by the reference
|
||||
home server* can be used. Since this is specific to a home server
|
||||
implementation, there may be variations in relation to registering/logging in
|
||||
which are not covered in extensive detail in this guide.
|
||||
|
||||
If you haven't already, get a home server up and running on
|
||||
``http://localhost:8008``.
|
||||
|
||||
|
||||
Accounts
|
||||
========
|
||||
Before you can send and receive messages, you must **register** for an account.
|
||||
If you already have an account, you must **login** into it.
|
||||
|
||||
.. NOTE::
|
||||
`Try out the fiddle`__
|
||||
|
||||
.. __: http://jsfiddle.net/gh/get/jquery/1.8.3/matrix-org/matrix-doc/tree/master/supporting-docs/howtos/jsfiddles/register_login
|
||||
|
||||
Registration
|
||||
------------
|
||||
The aim of registration is to get a user ID and access token which you will need
|
||||
when accessing other APIs::
|
||||
|
||||
curl -XPOST -d '{"user":"example", "password":"wordpass", "type":"m.login.password"}' "http://localhost:8008/_matrix/client/api/v1/register"
|
||||
|
||||
{
|
||||
"access_token": "QGV4YW1wbGU6bG9jYWxob3N0.AqdSzFmFYrLrTmteXc",
|
||||
"home_server": "localhost",
|
||||
"user_id": "@example:localhost"
|
||||
}
|
||||
|
||||
NB: If a ``user`` is not specified, one will be randomly generated for you.
|
||||
If you do not specify a ``password``, you will be unable to login to the account
|
||||
if you forget the ``access_token``.
|
||||
|
||||
Implementation note: The matrix specification does not enforce how users
|
||||
register with a server. It just specifies the URL path and absolute minimum
|
||||
keys. The reference home server uses a username/password to authenticate user,
|
||||
but other home servers may use different methods. This is why you need to
|
||||
specify the ``type`` of method.
|
||||
|
||||
Login
|
||||
-----
|
||||
The aim when logging in is to get an access token for your existing user ID::
|
||||
|
||||
curl -XGET "http://localhost:8008/_matrix/client/api/v1/login"
|
||||
|
||||
{
|
||||
"flows": [
|
||||
{
|
||||
"type": "m.login.password"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
curl -XPOST -d '{"type":"m.login.password", "user":"example", "password":"wordpass"}' "http://localhost:8008/_matrix/client/api/v1/login"
|
||||
|
||||
{
|
||||
"access_token": "QGV4YW1wbGU6bG9jYWxob3N0.vRDLTgxefmKWQEtgGd",
|
||||
"home_server": "localhost",
|
||||
"user_id": "@example:localhost"
|
||||
}
|
||||
|
||||
Implementation note: Different home servers may implement different methods for
|
||||
logging in to an existing account. In order to check that you know how to login
|
||||
to this home server, you must perform a ``GET`` first and make sure you
|
||||
recognise the login type. If you do not know how to login, you can
|
||||
``GET /login/fallback`` which will return a basic webpage which you can use to
|
||||
login. The reference home server implementation support username/password login,
|
||||
but other home servers may support different login methods (e.g. OAuth2).
|
||||
|
||||
|
||||
Communicating
|
||||
=============
|
||||
|
||||
In order to communicate with another user, you must **create a room** with that
|
||||
user and **send a message** to that room.
|
||||
|
||||
.. NOTE::
|
||||
`Try out the fiddle`__
|
||||
|
||||
.. __: http://jsfiddle.net/gh/get/jquery/1.8.3/matrix-org/matrix-doc/tree/master/supporting-docs/howtos/jsfiddles/create_room_send_msg
|
||||
|
||||
Creating a room
|
||||
---------------
|
||||
If you want to send a message to someone, you have to be in a room with them. To
|
||||
create a room::
|
||||
|
||||
curl -XPOST -d '{"room_alias_name":"tutorial"}' "http://localhost:8008/_matrix/client/api/v1/createRoom?access_token=YOUR_ACCESS_TOKEN"
|
||||
|
||||
{
|
||||
"room_alias": "#tutorial:localhost",
|
||||
"room_id": "!CvcvRuDYDzTOzfKKgh:localhost"
|
||||
}
|
||||
|
||||
The "room alias" is a human-readable string which can be shared with other users
|
||||
so they can join a room, rather than the room ID which is a randomly generated
|
||||
string. You can have multiple room aliases per room.
|
||||
|
||||
.. TODO(kegan)
|
||||
How to add/remove aliases from an existing room.
|
||||
|
||||
|
||||
Sending messages
|
||||
----------------
|
||||
You can now send messages to this room::
|
||||
|
||||
curl -XPOST -d '{"msgtype":"m.text", "body":"hello"}' "http://localhost:8008/_matrix/client/api/v1/rooms/%21CvcvRuDYDzTOzfKKgh%3Alocalhost/send/m.room.message?access_token=YOUR_ACCESS_TOKEN"
|
||||
|
||||
{
|
||||
"event_id": "YUwRidLecu"
|
||||
}
|
||||
|
||||
The event ID returned is a unique ID which identifies this message.
|
||||
|
||||
NB: There are no limitations to the types of messages which can be exchanged.
|
||||
The only requirement is that ``"msgtype"`` is specified. The Matrix
|
||||
specification outlines the following standard types: ``m.text``, ``m.image``,
|
||||
``m.audio``, ``m.video``, ``m.location``, ``m.emote``. See the specification for
|
||||
more information on these types.
|
||||
|
||||
Users and rooms
|
||||
===============
|
||||
|
||||
Each room can be configured to allow or disallow certain rules. In particular,
|
||||
these rules may specify if you require an **invitation** from someone already in
|
||||
the room in order to **join the room**. In addition, you may also be able to
|
||||
join a room **via a room alias** if one was set up.
|
||||
|
||||
.. NOTE::
|
||||
`Try out the fiddle`__
|
||||
|
||||
.. __: http://jsfiddle.net/gh/get/jquery/1.8.3/matrix-org/matrix-doc/tree/master/supporting-docs/howtos/jsfiddles/room_memberships
|
||||
|
||||
Inviting a user to a room
|
||||
-------------------------
|
||||
You can directly invite a user to a room like so::
|
||||
|
||||
curl -XPOST -d '{"user_id":"@myfriend:localhost"}' "http://localhost:8008/_matrix/client/api/v1/rooms/%21CvcvRuDYDzTOzfKKgh%3Alocalhost/invite?access_token=YOUR_ACCESS_TOKEN"
|
||||
|
||||
This informs ``@myfriend:localhost`` of the room ID
|
||||
``!CvcvRuDYDzTOzfKKgh:localhost`` and allows them to join the room.
|
||||
|
||||
Joining a room via an invite
|
||||
----------------------------
|
||||
If you receive an invite, you can join the room::
|
||||
|
||||
curl -XPOST -d '{}' "http://localhost:8008/_matrix/client/api/v1/rooms/%21CvcvRuDYDzTOzfKKgh%3Alocalhost/join?access_token=YOUR_ACCESS_TOKEN"
|
||||
|
||||
NB: Only the person invited (``@myfriend:localhost``) can change the membership
|
||||
state to ``"join"``. Repeatedly joining a room does nothing.
|
||||
|
||||
Joining a room via an alias
|
||||
---------------------------
|
||||
Alternatively, if you know the room alias for this room and the room config
|
||||
allows it, you can directly join a room via the alias::
|
||||
|
||||
curl -XPOST -d '{}' "http://localhost:8008/_matrix/client/api/v1/join/%23tutorial%3Alocalhost?access_token=YOUR_ACCESS_TOKEN"
|
||||
|
||||
{
|
||||
"room_id": "!CvcvRuDYDzTOzfKKgh:localhost"
|
||||
}
|
||||
|
||||
You will need to use the room ID when sending messages, not the room alias.
|
||||
|
||||
NB: If the room is configured to be an invite-only room, you will still require
|
||||
an invite in order to join the room even though you know the room alias. As a
|
||||
result, it is more common to see a room alias in relation to a public room,
|
||||
which do not require invitations.
|
||||
|
||||
Getting events
|
||||
==============
|
||||
An event is some interesting piece of data that a client may be interested in.
|
||||
It can be a message in a room, a room invite, etc. There are many different ways
|
||||
of getting events, depending on what the client already knows.
|
||||
|
||||
.. NOTE::
|
||||
`Try out the fiddle`__
|
||||
|
||||
.. __: http://jsfiddle.net/gh/get/jquery/1.8.3/matrix-org/matrix-doc/tree/master/supporting-docs/howtos/jsfiddles/event_stream
|
||||
|
||||
Getting all state
|
||||
-----------------
|
||||
If the client doesn't know any information on the rooms the user is
|
||||
invited/joined on, they can get all the user's state for all rooms::
|
||||
|
||||
curl -XGET "http://localhost:8008/_matrix/client/api/v1/initialSync?access_token=YOUR_ACCESS_TOKEN"
|
||||
|
||||
{
|
||||
"end": "s39_18_0",
|
||||
"presence": [
|
||||
{
|
||||
"content": {
|
||||
"last_active_ago": 1061436,
|
||||
"user_id": "@example:localhost"
|
||||
},
|
||||
"type": "m.presence"
|
||||
}
|
||||
],
|
||||
"rooms": [
|
||||
{
|
||||
"membership": "join",
|
||||
"messages": {
|
||||
"chunk": [
|
||||
{
|
||||
"content": {
|
||||
"@example:localhost": 10,
|
||||
"default": 0
|
||||
},
|
||||
"event_id": "wAumPSTsWF",
|
||||
"required_power_level": 10,
|
||||
"room_id": "!MkDbyRqnvTYnoxjLYx:localhost",
|
||||
"state_key": "",
|
||||
"ts": 1409665585188,
|
||||
"type": "m.room.power_levels",
|
||||
"user_id": "@example:localhost"
|
||||
},
|
||||
{
|
||||
"content": {
|
||||
"join_rule": "public"
|
||||
},
|
||||
"event_id": "jrLVqKHKiI",
|
||||
"required_power_level": 10,
|
||||
"room_id": "!MkDbyRqnvTYnoxjLYx:localhost",
|
||||
"state_key": "",
|
||||
"ts": 1409665585188,
|
||||
"type": "m.room.join_rules",
|
||||
"user_id": "@example:localhost"
|
||||
},
|
||||
{
|
||||
"content": {
|
||||
"level": 10
|
||||
},
|
||||
"event_id": "WpmTgsNWUZ",
|
||||
"required_power_level": 10,
|
||||
"room_id": "!MkDbyRqnvTYnoxjLYx:localhost",
|
||||
"state_key": "",
|
||||
"ts": 1409665585188,
|
||||
"type": "m.room.add_state_level",
|
||||
"user_id": "@example:localhost"
|
||||
},
|
||||
{
|
||||
"content": {
|
||||
"level": 0
|
||||
},
|
||||
"event_id": "qUMBJyKsTQ",
|
||||
"required_power_level": 10,
|
||||
"room_id": "!MkDbyRqnvTYnoxjLYx:localhost",
|
||||
"state_key": "",
|
||||
"ts": 1409665585188,
|
||||
"type": "m.room.send_event_level",
|
||||
"user_id": "@example:localhost"
|
||||
},
|
||||
{
|
||||
"content": {
|
||||
"ban_level": 5,
|
||||
"kick_level": 5
|
||||
},
|
||||
"event_id": "YAaDmKvoUW",
|
||||
"required_power_level": 10,
|
||||
"room_id": "!MkDbyRqnvTYnoxjLYx:localhost",
|
||||
"state_key": "",
|
||||
"ts": 1409665585188,
|
||||
"type": "m.room.ops_levels",
|
||||
"user_id": "@example:localhost"
|
||||
},
|
||||
{
|
||||
"content": {
|
||||
"avatar_url": null,
|
||||
"displayname": null,
|
||||
"membership": "join"
|
||||
},
|
||||
"event_id": "RJbPMtCutf",
|
||||
"membership": "join",
|
||||
"room_id": "!MkDbyRqnvTYnoxjLYx:localhost",
|
||||
"state_key": "@example:localhost",
|
||||
"ts": 1409665586730,
|
||||
"type": "m.room.member",
|
||||
"user_id": "@example:localhost"
|
||||
},
|
||||
{
|
||||
"content": {
|
||||
"body": "hello",
|
||||
"hsob_ts": 1409665660439,
|
||||
"msgtype": "m.text"
|
||||
},
|
||||
"event_id": "YUwRidLecu",
|
||||
"room_id": "!MkDbyRqnvTYnoxjLYx:localhost",
|
||||
"ts": 1409665660439,
|
||||
"type": "m.room.message",
|
||||
"user_id": "@example:localhost"
|
||||
},
|
||||
{
|
||||
"content": {
|
||||
"membership": "invite"
|
||||
},
|
||||
"event_id": "YjNuBKnPsb",
|
||||
"membership": "invite",
|
||||
"room_id": "!MkDbyRqnvTYnoxjLYx:localhost",
|
||||
"state_key": "@myfriend:localhost",
|
||||
"ts": 1409666426819,
|
||||
"type": "m.room.member",
|
||||
"user_id": "@example:localhost"
|
||||
},
|
||||
{
|
||||
"content": {
|
||||
"avatar_url": null,
|
||||
"displayname": null,
|
||||
"membership": "join",
|
||||
"prev": "join"
|
||||
},
|
||||
"event_id": "KWwdDjNZnm",
|
||||
"membership": "join",
|
||||
"room_id": "!MkDbyRqnvTYnoxjLYx:localhost",
|
||||
"state_key": "@example:localhost",
|
||||
"ts": 1409666551582,
|
||||
"type": "m.room.member",
|
||||
"user_id": "@example:localhost"
|
||||
},
|
||||
{
|
||||
"content": {
|
||||
"avatar_url": null,
|
||||
"displayname": null,
|
||||
"membership": "join"
|
||||
},
|
||||
"event_id": "JFLVteSvQc",
|
||||
"membership": "join",
|
||||
"room_id": "!MkDbyRqnvTYnoxjLYx:localhost",
|
||||
"state_key": "@example:localhost",
|
||||
"ts": 1409666587265,
|
||||
"type": "m.room.member",
|
||||
"user_id": "@example:localhost"
|
||||
}
|
||||
],
|
||||
"end": "s39_18_0",
|
||||
"start": "t1-11_18_0"
|
||||
},
|
||||
"room_id": "!MkDbyRqnvTYnoxjLYx:localhost",
|
||||
"state": [
|
||||
{
|
||||
"content": {
|
||||
"creator": "@example:localhost"
|
||||
},
|
||||
"event_id": "dMUoqVTZca",
|
||||
"required_power_level": 10,
|
||||
"room_id": "!MkDbyRqnvTYnoxjLYx:localhost",
|
||||
"state_key": "",
|
||||
"ts": 1409665585188,
|
||||
"type": "m.room.create",
|
||||
"user_id": "@example:localhost"
|
||||
},
|
||||
{
|
||||
"content": {
|
||||
"@example:localhost": 10,
|
||||
"default": 0
|
||||
},
|
||||
"event_id": "wAumPSTsWF",
|
||||
"required_power_level": 10,
|
||||
"room_id": "!MkDbyRqnvTYnoxjLYx:localhost",
|
||||
"state_key": "",
|
||||
"ts": 1409665585188,
|
||||
"type": "m.room.power_levels",
|
||||
"user_id": "@example:localhost"
|
||||
},
|
||||
{
|
||||
"content": {
|
||||
"join_rule": "public"
|
||||
},
|
||||
"event_id": "jrLVqKHKiI",
|
||||
"required_power_level": 10,
|
||||
"room_id": "!MkDbyRqnvTYnoxjLYx:localhost",
|
||||
"state_key": "",
|
||||
"ts": 1409665585188,
|
||||
"type": "m.room.join_rules",
|
||||
"user_id": "@example:localhost"
|
||||
},
|
||||
{
|
||||
"content": {
|
||||
"level": 10
|
||||
},
|
||||
"event_id": "WpmTgsNWUZ",
|
||||
"required_power_level": 10,
|
||||
"room_id": "!MkDbyRqnvTYnoxjLYx:localhost",
|
||||
"state_key": "",
|
||||
"ts": 1409665585188,
|
||||
"type": "m.room.add_state_level",
|
||||
"user_id": "@example:localhost"
|
||||
},
|
||||
{
|
||||
"content": {
|
||||
"level": 0
|
||||
},
|
||||
"event_id": "qUMBJyKsTQ",
|
||||
"required_power_level": 10,
|
||||
"room_id": "!MkDbyRqnvTYnoxjLYx:localhost",
|
||||
"state_key": "",
|
||||
"ts": 1409665585188,
|
||||
"type": "m.room.send_event_level",
|
||||
"user_id": "@example:localhost"
|
||||
},
|
||||
{
|
||||
"content": {
|
||||
"ban_level": 5,
|
||||
"kick_level": 5
|
||||
},
|
||||
"event_id": "YAaDmKvoUW",
|
||||
"required_power_level": 10,
|
||||
"room_id": "!MkDbyRqnvTYnoxjLYx:localhost",
|
||||
"state_key": "",
|
||||
"ts": 1409665585188,
|
||||
"type": "m.room.ops_levels",
|
||||
"user_id": "@example:localhost"
|
||||
},
|
||||
{
|
||||
"content": {
|
||||
"membership": "invite"
|
||||
},
|
||||
"event_id": "YjNuBKnPsb",
|
||||
"membership": "invite",
|
||||
"room_id": "!MkDbyRqnvTYnoxjLYx:localhost",
|
||||
"state_key": "@myfriend:localhost",
|
||||
"ts": 1409666426819,
|
||||
"type": "m.room.member",
|
||||
"user_id": "@example:localhost"
|
||||
},
|
||||
{
|
||||
"content": {
|
||||
"avatar_url": null,
|
||||
"displayname": null,
|
||||
"membership": "join"
|
||||
},
|
||||
"event_id": "JFLVteSvQc",
|
||||
"membership": "join",
|
||||
"room_id": "!MkDbyRqnvTYnoxjLYx:localhost",
|
||||
"state_key": "@example:localhost",
|
||||
"ts": 1409666587265,
|
||||
"type": "m.room.member",
|
||||
"user_id": "@example:localhost"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
This returns all the room information the user is invited/joined on, as well as
|
||||
all of the presences relevant for these rooms. This can be a LOT of data. You
|
||||
may just want the most recent event for each room. This can be achieved by
|
||||
applying query parameters to ``limit`` this request::
|
||||
|
||||
curl -XGET "http://localhost:8008/_matrix/client/api/v1/initialSync?limit=1&access_token=YOUR_ACCESS_TOKEN"
|
||||
|
||||
{
|
||||
"end": "s39_18_0",
|
||||
"presence": [
|
||||
{
|
||||
"content": {
|
||||
"last_active_ago": 1279484,
|
||||
"user_id": "@example:localhost"
|
||||
},
|
||||
"type": "m.presence"
|
||||
}
|
||||
],
|
||||
"rooms": [
|
||||
{
|
||||
"membership": "join",
|
||||
"messages": {
|
||||
"chunk": [
|
||||
{
|
||||
"content": {
|
||||
"avatar_url": null,
|
||||
"displayname": null,
|
||||
"membership": "join"
|
||||
},
|
||||
"event_id": "JFLVteSvQc",
|
||||
"membership": "join",
|
||||
"room_id": "!MkDbyRqnvTYnoxjLYx:localhost",
|
||||
"state_key": "@example:localhost",
|
||||
"ts": 1409666587265,
|
||||
"type": "m.room.member",
|
||||
"user_id": "@example:localhost"
|
||||
}
|
||||
],
|
||||
"end": "s39_18_0",
|
||||
"start": "t10-30_18_0"
|
||||
},
|
||||
"room_id": "!MkDbyRqnvTYnoxjLYx:localhost",
|
||||
"state": [
|
||||
{
|
||||
"content": {
|
||||
"creator": "@example:localhost"
|
||||
},
|
||||
"event_id": "dMUoqVTZca",
|
||||
"required_power_level": 10,
|
||||
"room_id": "!MkDbyRqnvTYnoxjLYx:localhost",
|
||||
"state_key": "",
|
||||
"ts": 1409665585188,
|
||||
"type": "m.room.create",
|
||||
"user_id": "@example:localhost"
|
||||
},
|
||||
{
|
||||
"content": {
|
||||
"@example:localhost": 10,
|
||||
"default": 0
|
||||
},
|
||||
"event_id": "wAumPSTsWF",
|
||||
"required_power_level": 10,
|
||||
"room_id": "!MkDbyRqnvTYnoxjLYx:localhost",
|
||||
"state_key": "",
|
||||
"ts": 1409665585188,
|
||||
"type": "m.room.power_levels",
|
||||
"user_id": "@example:localhost"
|
||||
},
|
||||
{
|
||||
"content": {
|
||||
"join_rule": "public"
|
||||
},
|
||||
"event_id": "jrLVqKHKiI",
|
||||
"required_power_level": 10,
|
||||
"room_id": "!MkDbyRqnvTYnoxjLYx:localhost",
|
||||
"state_key": "",
|
||||
"ts": 1409665585188,
|
||||
"type": "m.room.join_rules",
|
||||
"user_id": "@example:localhost"
|
||||
},
|
||||
{
|
||||
"content": {
|
||||
"level": 10
|
||||
},
|
||||
"event_id": "WpmTgsNWUZ",
|
||||
"required_power_level": 10,
|
||||
"room_id": "!MkDbyRqnvTYnoxjLYx:localhost",
|
||||
"state_key": "",
|
||||
"ts": 1409665585188,
|
||||
"type": "m.room.add_state_level",
|
||||
"user_id": "@example:localhost"
|
||||
},
|
||||
{
|
||||
"content": {
|
||||
"level": 0
|
||||
},
|
||||
"event_id": "qUMBJyKsTQ",
|
||||
"required_power_level": 10,
|
||||
"room_id": "!MkDbyRqnvTYnoxjLYx:localhost",
|
||||
"state_key": "",
|
||||
"ts": 1409665585188,
|
||||
"type": "m.room.send_event_level",
|
||||
"user_id": "@example:localhost"
|
||||
},
|
||||
{
|
||||
"content": {
|
||||
"ban_level": 5,
|
||||
"kick_level": 5
|
||||
},
|
||||
"event_id": "YAaDmKvoUW",
|
||||
"required_power_level": 10,
|
||||
"room_id": "!MkDbyRqnvTYnoxjLYx:localhost",
|
||||
"state_key": "",
|
||||
"ts": 1409665585188,
|
||||
"type": "m.room.ops_levels",
|
||||
"user_id": "@example:localhost"
|
||||
},
|
||||
{
|
||||
"content": {
|
||||
"membership": "invite"
|
||||
},
|
||||
"event_id": "YjNuBKnPsb",
|
||||
"membership": "invite",
|
||||
"room_id": "!MkDbyRqnvTYnoxjLYx:localhost",
|
||||
"state_key": "@myfriend:localhost",
|
||||
"ts": 1409666426819,
|
||||
"type": "m.room.member",
|
||||
"user_id": "@example:localhost"
|
||||
},
|
||||
{
|
||||
"content": {
|
||||
"avatar_url": null,
|
||||
"displayname": null,
|
||||
"membership": "join"
|
||||
},
|
||||
"event_id": "JFLVteSvQc",
|
||||
"membership": "join",
|
||||
"room_id": "!MkDbyRqnvTYnoxjLYx:localhost",
|
||||
"state_key": "@example:localhost",
|
||||
"ts": 1409666587265,
|
||||
"type": "m.room.member",
|
||||
"user_id": "@example:localhost"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
Getting live state
|
||||
------------------
|
||||
Once you know which rooms the client has previously interacted with, you need to
|
||||
listen for incoming events. This can be done like so::
|
||||
|
||||
curl -XGET "http://localhost:8008/_matrix/client/api/v1/events?access_token=YOUR_ACCESS_TOKEN"
|
||||
|
||||
{
|
||||
"chunk": [],
|
||||
"end": "s39_18_0",
|
||||
"start": "s39_18_0"
|
||||
}
|
||||
|
||||
This will block waiting for an incoming event, timing out after several seconds.
|
||||
Even if there are no new events (as in the example above), there will be some
|
||||
pagination stream response keys. The client should make subsequent requests
|
||||
using the value of the ``"end"`` key (in this case ``s39_18_0``) as the ``from``
|
||||
query parameter e.g. ``http://localhost:8008/_matrix/client/api/v1/events?access
|
||||
_token=YOUR_ACCESS_TOKEN&from=s39_18_0``. This value should be stored so when the
|
||||
client reopens your app after a period of inactivity, you can resume from where
|
||||
you got up to in the event stream. If it has been a long period of inactivity,
|
||||
there may be LOTS of events waiting for the user. In this case, you may wish to
|
||||
get all state instead and then resume getting live state from a newer end token.
|
||||
|
||||
NB: The timeout can be changed by adding a ``timeout`` query parameter, which is
|
||||
in milliseconds. A timeout of 0 will not block.
|
||||
|
||||
|
||||
Example application
|
||||
-------------------
|
||||
The following example demonstrates registration and login, live event streaming,
|
||||
creating and joining rooms, sending messages, getting member lists and getting
|
||||
historical messages for a room. This covers most functionality of a messaging
|
||||
application.
|
||||
|
||||
.. NOTE::
|
||||
`Try out the fiddle`__
|
||||
|
||||
.. __: http://jsfiddle.net/gh/get/jquery/1.8.3/matrix-org/matrix-doc/tree/master/supporting-docs/howtos/jsfiddles/example_app
|
@ -0,0 +1,120 @@
|
||||
---
|
||||
layout: post
|
||||
title: Getting involved
|
||||
categories: guides
|
||||
---
|
||||
|
||||
# How can I get involved?
|
||||
Matrix is an ecosystem consisting of several apps written by lots of people. We at Matrix.org have written one server and a few clients, and people in the community have also written several clients, servers, and Application Services. We are collecting [a list of all known Matrix-apps](https://matrix.org/blog/try-matrix-now/).
|
||||
|
||||
|
|
||||
|
||||
You have a few options when it comes to getting involved: if you just want to use Matrix, you can [register an account on a public server using a public webclient](#reg). If you have a virtual private server (VPS) or similar, you might want to [run a server and/or client yourself](#run). If you want to look under the hood, you can [checkout the code and modify it - or write your own client or server](#checkout). Or you can write an [Application Service](#as), for example a bridge to an existing ecosystem.
|
||||
|
||||
|
|
||||
|
||||
<a class="anchor" id="reg"></a>
|
||||
|
||||
## Access Matrix via a public webclient/server
|
||||
|
||||
The easiest thing to do if you want to just have a play, is to use our reference webclient and create a user on the matrix.org homeserver. You do that by visiting http://matrix.org/beta/, selecting "Create account" and choosing your userID and password on the next page. You can also add your email, but this is optional (adding it will make it easier for your friends to find your Matrix user in the future).
|
||||
|
||||
|
|
||||
|
||||
At the bottom of the account creation page, you can pick the homeserver and identity server you want to use. In this case, we are using matrix.org's homeserver, so just leave it as-is. Your full Matrix-userID will be formed partly from the hostname your server is running as, and partly from an userID you specify when you create the account. For example, if you put bob as your userID, your full Matrix-userID will be @bob:matrix.org ("bob on matrix.org").
|
||||
|
||||
|
|
||||
|
||||
You can use multiple clients with the same user, so you might want to also look at our [Android](https://github.com/matrix-org/matrix-android-console) or [iOS](https://github.com/matrix-org/matrix-ios-console) clients for your mobile phone!
|
||||
|
||||
|
|
||||
|
||||
<a class="anchor" id="run"></a>
|
||||
|
||||
## Run a server and/or client yourself
|
||||
|
||||
### Running your own client:
|
||||
|
||||
You can run your own Matrix client; there are [numerous clients available](https://matrix.org/blog/try-matrix-now/). You can take Matrix.org's [reference client](https://github.com/matrix-org/matrix-angular-sdk) and use it as-is - or modify it any way you want! Since it's written in JavaScript, running a client is [really easy](https://github.com/matrix-org/matrix-angular-sdk#running)!
|
||||
|
||||
|
|
||||
|
||||
### Running your own homeserver:
|
||||
|
||||
One of the core features of Matrix is that anyone can run a homeserver and join the federated network on equal terms (there is no hierarchy). If you want to set up your own homeserver, please see the relevant docs of the server you want to run. If you want to run Matrix.org's reference homeserver, please consult the [readme of the Synapse project](https://github.com/matrix-org/synapse/blob/master/README.rst).
|
||||
|
||||
|
|
||||
|
||||
Note that Synapse comes with a bundled Matrix.org webclient - but you can tell it to use your [development checkout snapshot instead](https://github.com/matrix-org/matrix-angular-sdk#matrix-angular-sdk) (or to not run a webclient at all via the "web_client: false" config option).
|
||||
|
||||
|
|
||||
|
||||
<a class="anchor" id="checkout"></a>
|
||||
|
||||
## Checkout our code - or write your own
|
||||
|
||||
As described above, you can clone our code and [run a server and/or client yourself](#run). Infact, all the code that we at Matrix.org write is available from [our github](http://github.com/matrix-org) - and other servers and clients may also be open sourced - see [our list of all known Matrix-apps](https://matrix.org/blog/try-matrix-now/).
|
||||
|
||||
|
|
||||
|
||||
You can also implement your own client or server - after all, Matrix is at its core "just" a specification of a protocol.
|
||||
|
||||
|
|
||||
|
||||
### Write your own client:
|
||||
|
||||
The [client-server API spec](http://matrix.org/docs/howtos/client-server.html) describes what API calls are available to clients, but a quick step-by-step guide would include:
|
||||
|
||||
|
|
||||
|
||||
1. Get a user either by registering your user in an existing client or running the [new-user script](https://github.com/matrix-org/synapse/blob/master/scripts/register_new_matrix_user) if you are running your own Synapse homeserver.
|
||||
|
||||
2. Assuming the homeserver you are using allows logins by password, log in via the login API:
|
||||
```
|
||||
curl -XPOST -d '{"type":"m.login.password", "user":"example", "password":"wordpass"}' "http://localhost:8008/_matrix/client/api/v1/login"
|
||||
```
|
||||
3. If successful, this returns the following, including an `access_token`:
|
||||
|
||||
{
|
||||
"access_token": "QGV4YW1wbGU6bG9jYWxob3N0.vRDLTgxefmKWQEtgGd",
|
||||
"home_server": "localhost",
|
||||
"user_id": "@example:localhost"
|
||||
}
|
||||
|
||||
4. This ``access_token`` will be used for authentication for the rest of your API calls. Potentially the next step you want is to make a call to the initialSync API and get the last x events from each room your user is in (via the limit parameter):
|
||||
```
|
||||
curl -XGET "http://localhost:8008/_matrix/client/api/v1/initialSync?limit=1&access_token=YOUR_ACCESS_TOKEN"
|
||||
```
|
||||
|
||||
5. In addition to the last x events for all the rooms the user is interested in, this returns all the presences relevant for these rooms. Once you know which rooms the client has previously interacted with, you need to listen for incoming events. This can be done like so:
|
||||
```
|
||||
curl -XGET "http://localhost:8008/_matrix/client/api/v1/events?access_token=YOUR_ACCESS_TOKEN"
|
||||
```
|
||||
|
||||
6. This request will block waiting for an incoming event, timing out after several seconds if there is no event, returning something like this:
|
||||
|
||||
{
|
||||
"chunk": [],
|
||||
"end": "s39_18_0",
|
||||
"start": "s39_18_0"
|
||||
}
|
||||
7. Even if there are no new events (as in the example above), there will be some pagination stream response keys. The client should make subsequent requests using the value of the "end" key (in this case s39_18_0) as the from query parameter e.g.
|
||||
```
|
||||
http://localhost:8008/_matrix/client/api/v1/events?access _token=YOUR_ACCESS_TOKEN&from=s39_18_0
|
||||
```
|
||||
|
||||
8. This ensures that you only get new events. Now you have initial rooms and presence, and a stream of events - a good client should be able to process all these events and present them to the user. And potentially you might want to add functionality to generate events as well (such as messages from the user, for example) - again please consult the [client-server API spec](http://matrix.org/docs/howtos/client-server.html)!
|
||||
|
||||
### Write your own server:
|
||||
|
||||
We are still working on the server-server spec, so the best thing to do if you are interested in writing a server, is to come talk to us in [#matrix:matrix.org](https://matrix.org/beta/#/room/%23matrix:matrix.org).
|
||||
|
||||
If you are interested in how federation works, please see the [federation API chapter in the spec](http://matrix.org/docs/spec/#federation-api).
|
||||
|
||||
|
|
||||
|
||||
<a class="anchor" id="as"></a>
|
||||
|
||||
## Write an Application Service:
|
||||
|
||||
One of our core developers, Kegan, wrote an excellent [blogpost about the Application Services API](https://matrix.org/blog/2015/03/02/introduction-to-application-services/), as well as a [blogpost about the Matrix<->IRC Application Service](https://matrix.org/blog/2015/04/22/matrix-irc-application-service/) - these are the best resources to consult if you want to write an Application Service yourself.
|
@ -0,0 +1,19 @@
|
||||
---
|
||||
layout: default
|
||||
---
|
||||
{% include site.css %}
|
||||
{% include basic.css %}
|
||||
{% include nature.css %}
|
||||
|
||||
<div class="post">
|
||||
|
||||
<header class="post-header">
|
||||
<div class="post-title">{{ page.title }}</div>
|
||||
<p class="post-meta">{{ page.date | date: "%b %-d, %Y" }}{% if page.author %} • {{ page.author }}{% endif %}{% if page.meta %} • {{ page.meta }}{% endif %}</p>
|
||||
</header>
|
||||
|
||||
<article class="post-content">
|
||||
{{ content }}
|
||||
</article>
|
||||
|
||||
</div>
|
@ -0,0 +1,204 @@
|
||||
/**
|
||||
* Reset some basic elements
|
||||
*/
|
||||
body, h1, h2, h3, h4, h5, h6,
|
||||
p, blockquote, pre, hr,
|
||||
dl, dd, ol, ul, figure {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Basic styling
|
||||
*/
|
||||
body {
|
||||
font-family: $base-font-family;
|
||||
font-size: $base-font-size;
|
||||
line-height: $base-line-height;
|
||||
font-weight: 300;
|
||||
color: $text-color;
|
||||
background-color: $background-color;
|
||||
-webkit-text-size-adjust: 100%;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Set `margin-bottom` to maintain vertical rhythm
|
||||
*/
|
||||
h1, h2, h3, h4, h5, h6,
|
||||
p, blockquote, pre,
|
||||
ul, ol, dl, figure,
|
||||
%vertical-rhythm {
|
||||
margin-bottom: $spacing-unit / 2;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Images
|
||||
*/
|
||||
img {
|
||||
max-width: 100%;
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Figures
|
||||
*/
|
||||
figure > img {
|
||||
display: block;
|
||||
}
|
||||
|
||||
figcaption {
|
||||
font-size: $small-font-size;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Lists
|
||||
*/
|
||||
ul, ol {
|
||||
margin-left: $spacing-unit;
|
||||
}
|
||||
|
||||
li {
|
||||
> ul,
|
||||
> ol {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Headings
|
||||
*/
|
||||
h1, h2, h3, h4, h5, h6 {
|
||||
font-weight: 300;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Links
|
||||
*/
|
||||
a {
|
||||
color: $brand-color;
|
||||
text-decoration: none;
|
||||
|
||||
&:visited {
|
||||
color: darken($brand-color, 15%);
|
||||
}
|
||||
|
||||
&:hover {
|
||||
color: $text-color;
|
||||
text-decoration: underline;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Blockquotes
|
||||
*/
|
||||
blockquote {
|
||||
color: $grey-color;
|
||||
border-left: 4px solid $grey-color-light;
|
||||
padding-left: $spacing-unit / 2;
|
||||
font-size: 18px;
|
||||
letter-spacing: -1px;
|
||||
font-style: italic;
|
||||
|
||||
> :last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Code formatting
|
||||
*/
|
||||
pre,
|
||||
code {
|
||||
font-size: 15px;
|
||||
border: 1px solid $grey-color-light;
|
||||
border-radius: 3px;
|
||||
background-color: #eef;
|
||||
}
|
||||
|
||||
code {
|
||||
padding: 1px 5px;
|
||||
}
|
||||
|
||||
pre {
|
||||
padding: 8px 12px;
|
||||
overflow-x: scroll;
|
||||
|
||||
> code {
|
||||
border: 0;
|
||||
padding-right: 0;
|
||||
padding-left: 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Wrapper
|
||||
*/
|
||||
.wrapper {
|
||||
max-width: -webkit-calc(#{$content-width} - (#{$spacing-unit} * 2));
|
||||
max-width: calc(#{$content-width} - (#{$spacing-unit} * 2));
|
||||
margin-right: auto;
|
||||
margin-left: auto;
|
||||
padding-right: $spacing-unit;
|
||||
padding-left: $spacing-unit;
|
||||
@extend %clearfix;
|
||||
|
||||
@include media-query($on-laptop) {
|
||||
max-width: -webkit-calc(#{$content-width} - (#{$spacing-unit}));
|
||||
max-width: calc(#{$content-width} - (#{$spacing-unit}));
|
||||
padding-right: $spacing-unit / 2;
|
||||
padding-left: $spacing-unit / 2;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Clearfix
|
||||
*/
|
||||
%clearfix {
|
||||
|
||||
&:after {
|
||||
content: "";
|
||||
display: table;
|
||||
clear: both;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Icons
|
||||
*/
|
||||
.icon {
|
||||
|
||||
> svg {
|
||||
display: inline-block;
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
vertical-align: middle;
|
||||
|
||||
path {
|
||||
fill: $grey-color;
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,236 @@
|
||||
/**
|
||||
* Site header
|
||||
*/
|
||||
.site-header {
|
||||
border-top: 5px solid $grey-color-dark;
|
||||
border-bottom: 1px solid $grey-color-light;
|
||||
min-height: 56px;
|
||||
|
||||
// Positioning context for the mobile navigation icon
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.site-title {
|
||||
font-size: 26px;
|
||||
line-height: 56px;
|
||||
letter-spacing: -1px;
|
||||
margin-bottom: 0;
|
||||
float: left;
|
||||
|
||||
&,
|
||||
&:visited {
|
||||
color: $grey-color-dark;
|
||||
}
|
||||
}
|
||||
|
||||
.site-nav {
|
||||
float: right;
|
||||
line-height: 56px;
|
||||
|
||||
.menu-icon {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.page-link {
|
||||
color: $text-color;
|
||||
line-height: $base-line-height;
|
||||
|
||||
// Gaps between nav items, but not on the first one
|
||||
&:not(:first-child) {
|
||||
margin-left: 20px;
|
||||
}
|
||||
}
|
||||
|
||||
@include media-query($on-palm) {
|
||||
position: absolute;
|
||||
top: 9px;
|
||||
right: 30px;
|
||||
background-color: $background-color;
|
||||
border: 1px solid $grey-color-light;
|
||||
border-radius: 5px;
|
||||
text-align: right;
|
||||
|
||||
.menu-icon {
|
||||
display: block;
|
||||
float: right;
|
||||
width: 36px;
|
||||
height: 26px;
|
||||
line-height: 0;
|
||||
padding-top: 10px;
|
||||
text-align: center;
|
||||
|
||||
> svg {
|
||||
width: 18px;
|
||||
height: 15px;
|
||||
|
||||
path {
|
||||
fill: $grey-color-dark;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.trigger {
|
||||
clear: both;
|
||||
display: none;
|
||||
}
|
||||
|
||||
&:hover .trigger {
|
||||
display: block;
|
||||
padding-bottom: 5px;
|
||||
}
|
||||
|
||||
.page-link {
|
||||
display: block;
|
||||
padding: 5px 10px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Site footer
|
||||
*/
|
||||
.site-footer {
|
||||
border-top: 1px solid $grey-color-light;
|
||||
padding: $spacing-unit 0;
|
||||
}
|
||||
|
||||
.footer-heading {
|
||||
font-size: 18px;
|
||||
margin-bottom: $spacing-unit / 2;
|
||||
}
|
||||
|
||||
.contact-list,
|
||||
.social-media-list {
|
||||
list-style: none;
|
||||
margin-left: 0;
|
||||
}
|
||||
|
||||
.footer-col-wrapper {
|
||||
font-size: 15px;
|
||||
color: $grey-color;
|
||||
margin-left: -$spacing-unit / 2;
|
||||
@extend %clearfix;
|
||||
}
|
||||
|
||||
.footer-col {
|
||||
float: left;
|
||||
margin-bottom: $spacing-unit / 2;
|
||||
padding-left: $spacing-unit / 2;
|
||||
}
|
||||
|
||||
.footer-col-1 {
|
||||
width: -webkit-calc(35% - (#{$spacing-unit} / 2));
|
||||
width: calc(35% - (#{$spacing-unit} / 2));
|
||||
}
|
||||
|
||||
.footer-col-2 {
|
||||
width: -webkit-calc(20% - (#{$spacing-unit} / 2));
|
||||
width: calc(20% - (#{$spacing-unit} / 2));
|
||||
}
|
||||
|
||||
.footer-col-3 {
|
||||
width: -webkit-calc(45% - (#{$spacing-unit} / 2));
|
||||
width: calc(45% - (#{$spacing-unit} / 2));
|
||||
}
|
||||
|
||||
@include media-query($on-laptop) {
|
||||
.footer-col-1,
|
||||
.footer-col-2 {
|
||||
width: -webkit-calc(50% - (#{$spacing-unit} / 2));
|
||||
width: calc(50% - (#{$spacing-unit} / 2));
|
||||
}
|
||||
|
||||
.footer-col-3 {
|
||||
width: -webkit-calc(100% - (#{$spacing-unit} / 2));
|
||||
width: calc(100% - (#{$spacing-unit} / 2));
|
||||
}
|
||||
}
|
||||
|
||||
@include media-query($on-palm) {
|
||||
.footer-col {
|
||||
float: none;
|
||||
width: -webkit-calc(100% - (#{$spacing-unit} / 2));
|
||||
width: calc(100% - (#{$spacing-unit} / 2));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Page content
|
||||
*/
|
||||
.page-content {
|
||||
padding: $spacing-unit 0;
|
||||
}
|
||||
|
||||
.page-heading {
|
||||
font-size: 20px;
|
||||
}
|
||||
|
||||
.post-list {
|
||||
margin-left: 0;
|
||||
list-style: none;
|
||||
|
||||
> li {
|
||||
margin-bottom: $spacing-unit;
|
||||
}
|
||||
}
|
||||
|
||||
.post-meta {
|
||||
font-size: $small-font-size;
|
||||
color: $grey-color;
|
||||
}
|
||||
|
||||
.post-link {
|
||||
display: block;
|
||||
font-size: 24px;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Posts
|
||||
*/
|
||||
.post-header {
|
||||
margin-bottom: $spacing-unit;
|
||||
}
|
||||
|
||||
.post-title {
|
||||
font-size: 42px;
|
||||
letter-spacing: -1px;
|
||||
line-height: 1;
|
||||
|
||||
@include media-query($on-laptop) {
|
||||
font-size: 36px;
|
||||
}
|
||||
}
|
||||
|
||||
.post-content {
|
||||
margin-bottom: $spacing-unit;
|
||||
|
||||
h2 {
|
||||
font-size: 32px;
|
||||
|
||||
@include media-query($on-laptop) {
|
||||
font-size: 28px;
|
||||
}
|
||||
}
|
||||
|
||||
h3 {
|
||||
font-size: 26px;
|
||||
|
||||
@include media-query($on-laptop) {
|
||||
font-size: 22px;
|
||||
}
|
||||
}
|
||||
|
||||
h4 {
|
||||
font-size: 20px;
|
||||
|
||||
@include media-query($on-laptop) {
|
||||
font-size: 18px;
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,67 @@
|
||||
/**
|
||||
* Syntax highlighting styles
|
||||
*/
|
||||
.highlight {
|
||||
background: #fff;
|
||||
@extend %vertical-rhythm;
|
||||
|
||||
.c { color: #998; font-style: italic } // Comment
|
||||
.err { color: #a61717; background-color: #e3d2d2 } // Error
|
||||
.k { font-weight: bold } // Keyword
|
||||
.o { font-weight: bold } // Operator
|
||||
.cm { color: #998; font-style: italic } // Comment.Multiline
|
||||
.cp { color: #999; font-weight: bold } // Comment.Preproc
|
||||
.c1 { color: #998; font-style: italic } // Comment.Single
|
||||
.cs { color: #999; font-weight: bold; font-style: italic } // Comment.Special
|
||||
.gd { color: #000; background-color: #fdd } // Generic.Deleted
|
||||
.gd .x { color: #000; background-color: #faa } // Generic.Deleted.Specific
|
||||
.ge { font-style: italic } // Generic.Emph
|
||||
.gr { color: #a00 } // Generic.Error
|
||||
.gh { color: #999 } // Generic.Heading
|
||||
.gi { color: #000; background-color: #dfd } // Generic.Inserted
|
||||
.gi .x { color: #000; background-color: #afa } // Generic.Inserted.Specific
|
||||
.go { color: #888 } // Generic.Output
|
||||
.gp { color: #555 } // Generic.Prompt
|
||||
.gs { font-weight: bold } // Generic.Strong
|
||||
.gu { color: #aaa } // Generic.Subheading
|
||||
.gt { color: #a00 } // Generic.Traceback
|
||||
.kc { font-weight: bold } // Keyword.Constant
|
||||
.kd { font-weight: bold } // Keyword.Declaration
|
||||
.kp { font-weight: bold } // Keyword.Pseudo
|
||||
.kr { font-weight: bold } // Keyword.Reserved
|
||||
.kt { color: #458; font-weight: bold } // Keyword.Type
|
||||
.m { color: #099 } // Literal.Number
|
||||
.s { color: #d14 } // Literal.String
|
||||
.na { color: #008080 } // Name.Attribute
|
||||
.nb { color: #0086B3 } // Name.Builtin
|
||||
.nc { color: #458; font-weight: bold } // Name.Class
|
||||
.no { color: #008080 } // Name.Constant
|
||||
.ni { color: #800080 } // Name.Entity
|
||||
.ne { color: #900; font-weight: bold } // Name.Exception
|
||||
.nf { color: #900; font-weight: bold } // Name.Function
|
||||
.nn { color: #555 } // Name.Namespace
|
||||
.nt { color: #000080 } // Name.Tag
|
||||
.nv { color: #008080 } // Name.Variable
|
||||
.ow { font-weight: bold } // Operator.Word
|
||||
.w { color: #bbb } // Text.Whitespace
|
||||
.mf { color: #099 } // Literal.Number.Float
|
||||
.mh { color: #099 } // Literal.Number.Hex
|
||||
.mi { color: #099 } // Literal.Number.Integer
|
||||
.mo { color: #099 } // Literal.Number.Oct
|
||||
.sb { color: #d14 } // Literal.String.Backtick
|
||||
.sc { color: #d14 } // Literal.String.Char
|
||||
.sd { color: #d14 } // Literal.String.Doc
|
||||
.s2 { color: #d14 } // Literal.String.Double
|
||||
.se { color: #d14 } // Literal.String.Escape
|
||||
.sh { color: #d14 } // Literal.String.Heredoc
|
||||
.si { color: #d14 } // Literal.String.Interpol
|
||||
.sx { color: #d14 } // Literal.String.Other
|
||||
.sr { color: #009926 } // Literal.String.Regex
|
||||
.s1 { color: #d14 } // Literal.String.Single
|
||||
.ss { color: #990073 } // Literal.String.Symbol
|
||||
.bp { color: #999 } // Name.Builtin.Pseudo
|
||||
.vc { color: #008080 } // Name.Variable.Class
|
||||
.vg { color: #008080 } // Name.Variable.Global
|
||||
.vi { color: #008080 } // Name.Variable.Instance
|
||||
.il { color: #099 } // Literal.Number.Integer.Long
|
||||
}
|
@ -0,0 +1,11 @@
|
||||
---
|
||||
layout: page
|
||||
title: About
|
||||
permalink: /about/
|
||||
---
|
||||
|
||||
This is the base Jekyll theme. You can find out more info about customizing your Jekyll theme, as well as basic Jekyll usage documentation at [jekyllrb.com](http://jekyllrb.com/)
|
||||
|
||||
You can find the source code for the Jekyll new theme at: [github.com/jglovier/jekyll-new](https://github.com/jglovier/jekyll-new)
|
||||
|
||||
You can find the source code for Jekyll at [github.com/jekyll/jekyll](https://github.com/jekyll/jekyll)
|
@ -0,0 +1,512 @@
|
||||
/*
|
||||
* basic.css
|
||||
* ~~~~~~~~~
|
||||
*
|
||||
* Sphinx stylesheet -- basic theme.
|
||||
*
|
||||
* :copyright: Copyright 2007-2010 by the Sphinx team, see AUTHORS.
|
||||
* :license: BSD, see LICENSE for details.
|
||||
*
|
||||
*/
|
||||
|
||||
/* -- main layout ----------------------------------------------------------- */
|
||||
|
||||
div.clearer {
|
||||
clear: both;
|
||||
}
|
||||
|
||||
/* -- relbar ---------------------------------------------------------------- */
|
||||
|
||||
div.related {
|
||||
width: 100%;
|
||||
font-size: 90%;
|
||||
}
|
||||
|
||||
div.related h3 {
|
||||
display: none;
|
||||
}
|
||||
|
||||
div.related ul {
|
||||
margin: 0;
|
||||
padding: 0 0 0 10px;
|
||||
list-style: none;
|
||||
}
|
||||
|
||||
div.related li {
|
||||
display: inline;
|
||||
}
|
||||
|
||||
div.related li.right {
|
||||
float: right;
|
||||
margin-right: 5px;
|
||||
}
|
||||
|
||||
/* -- sidebar --------------------------------------------------------------- */
|
||||
|
||||
div.sphinxsidebarwrapper {
|
||||
padding: 10px 5px 0 10px;
|
||||
}
|
||||
|
||||
div.sphinxsidebar {
|
||||
float: left;
|
||||
width: 230px;
|
||||
margin-left: -100%;
|
||||
font-size: 90%;
|
||||
}
|
||||
|
||||
div.sphinxsidebar ul {
|
||||
list-style: none;
|
||||
}
|
||||
|
||||
div.sphinxsidebar ul ul,
|
||||
div.sphinxsidebar ul.want-points {
|
||||
margin-left: 20px;
|
||||
list-style: square;
|
||||
}
|
||||
|
||||
div.sphinxsidebar ul ul {
|
||||
margin-top: 0;
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
div.sphinxsidebar form {
|
||||
margin-top: 10px;
|
||||
}
|
||||
|
||||
div.sphinxsidebar input {
|
||||
border: 1px solid #98dbcc;
|
||||
font-family: sans-serif;
|
||||
font-size: 1em;
|
||||
}
|
||||
|
||||
img {
|
||||
border: 0;
|
||||
}
|
||||
|
||||
/* -- search page ----------------------------------------------------------- */
|
||||
|
||||
ul.search {
|
||||
margin: 10px 0 0 20px;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
ul.search li {
|
||||
padding: 5px 0 5px 20px;
|
||||
background-image: url(file.png);
|
||||
background-repeat: no-repeat;
|
||||
background-position: 0 7px;
|
||||
}
|
||||
|
||||
ul.search li a {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
ul.search li div.context {
|
||||
color: #888;
|
||||
margin: 2px 0 0 30px;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
ul.keywordmatches li.goodmatch a {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
/* -- index page ------------------------------------------------------------ */
|
||||
|
||||
table.contentstable {
|
||||
width: 90%;
|
||||
}
|
||||
|
||||
table.contentstable p.biglink {
|
||||
line-height: 150%;
|
||||
}
|
||||
|
||||
a.biglink {
|
||||
font-size: 1.3em;
|
||||
}
|
||||
|
||||
span.linkdescr {
|
||||
font-style: italic;
|
||||
padding-top: 5px;
|
||||
font-size: 90%;
|
||||
}
|
||||
|
||||
/* -- general index --------------------------------------------------------- */
|
||||
|
||||
table.indextable {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
table.indextable td {
|
||||
text-align: left;
|
||||
vertical-align: top;
|
||||
}
|
||||
|
||||
table.indextable dl, table.indextable dd {
|
||||
margin-top: 0;
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
table.indextable tr.pcap {
|
||||
height: 10px;
|
||||
}
|
||||
|
||||
table.indextable tr.cap {
|
||||
margin-top: 10px;
|
||||
background-color: #f2f2f2;
|
||||
}
|
||||
|
||||
img.toggler {
|
||||
margin-right: 3px;
|
||||
margin-top: 3px;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
div.modindex-jumpbox {
|
||||
border-top: 1px solid #ddd;
|
||||
border-bottom: 1px solid #ddd;
|
||||
margin: 1em 0 1em 0;
|
||||
padding: 0.4em;
|
||||
}
|
||||
|
||||
div.genindex-jumpbox {
|
||||
border-top: 1px solid #ddd;
|
||||
border-bottom: 1px solid #ddd;
|
||||
margin: 1em 0 1em 0;
|
||||
padding: 0.4em;
|
||||
}
|
||||
|
||||
/* -- general body styles --------------------------------------------------- */
|
||||
|
||||
a.headerlink {
|
||||
visibility: hidden;
|
||||
}
|
||||
|
||||
h1:hover > a.headerlink,
|
||||
h2:hover > a.headerlink,
|
||||
h3:hover > a.headerlink,
|
||||
h4:hover > a.headerlink,
|
||||
h5:hover > a.headerlink,
|
||||
h6:hover > a.headerlink,
|
||||
dt:hover > a.headerlink {
|
||||
visibility: visible;
|
||||
}
|
||||
|
||||
div.document p.caption {
|
||||
text-align: inherit;
|
||||
}
|
||||
|
||||
div.document td {
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.field-list ul {
|
||||
padding-left: 1em;
|
||||
}
|
||||
|
||||
.first {
|
||||
margin-top: 0 !important;
|
||||
}
|
||||
|
||||
p.rubric {
|
||||
margin-top: 30px;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.align-left {
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.align-center {
|
||||
clear: both;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.align-right {
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
/* -- sidebars -------------------------------------------------------------- */
|
||||
|
||||
div.sidebar {
|
||||
margin: 0 0 0.5em 1em;
|
||||
border: 1px solid #ddb;
|
||||
padding: 7px 7px 0 7px;
|
||||
background-color: #ffe;
|
||||
width: 40%;
|
||||
float: right;
|
||||
}
|
||||
|
||||
p.sidebar-title {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
/* -- topics ---------------------------------------------------------------- */
|
||||
|
||||
div.topic {
|
||||
border: 1px solid #ccc;
|
||||
padding: 7px 7px 0 7px;
|
||||
margin: 10px 0 10px 0;
|
||||
}
|
||||
|
||||
p.topic-title {
|
||||
font-size: 1.1em;
|
||||
font-weight: bold;
|
||||
margin-top: 10px;
|
||||
}
|
||||
|
||||
/* -- admonitions ----------------------------------------------------------- */
|
||||
|
||||
div.admonition {
|
||||
margin-top: 10px;
|
||||
margin-bottom: 10px;
|
||||
padding: 7px;
|
||||
}
|
||||
|
||||
div.admonition dt {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
div.admonition dl {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
p.admonition-title {
|
||||
margin: 0px 10px 5px 0px;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
div.document p.centered {
|
||||
text-align: center;
|
||||
margin-top: 25px;
|
||||
}
|
||||
|
||||
/* -- tables ---------------------------------------------------------------- */
|
||||
|
||||
table.docutils {
|
||||
border: 0;
|
||||
border-collapse: collapse;
|
||||
}
|
||||
|
||||
table.docutils td, table.docutils th {
|
||||
padding: 1px 8px 1px 5px;
|
||||
border-top: 0;
|
||||
border-left: 0;
|
||||
border-right: 0;
|
||||
border-bottom: 1px solid #aaa;
|
||||
}
|
||||
|
||||
table.field-list td, table.field-list th {
|
||||
border: 0 !important;
|
||||
}
|
||||
|
||||
table.footnote td, table.footnote th {
|
||||
border: 0 !important;
|
||||
}
|
||||
|
||||
th {
|
||||
text-align: left;
|
||||
padding-right: 5px;
|
||||
}
|
||||
|
||||
table.citation {
|
||||
border-left: solid 1px gray;
|
||||
margin-left: 1px;
|
||||
}
|
||||
|
||||
table.citation td {
|
||||
border-bottom: none;
|
||||
}
|
||||
|
||||
/* -- other body styles ----------------------------------------------------- */
|
||||
|
||||
ol.arabic {
|
||||
list-style: decimal;
|
||||
}
|
||||
|
||||
ol.loweralpha {
|
||||
list-style: lower-alpha;
|
||||
}
|
||||
|
||||
ol.upperalpha {
|
||||
list-style: upper-alpha;
|
||||
}
|
||||
|
||||
ol.lowerroman {
|
||||
list-style: lower-roman;
|
||||
}
|
||||
|
||||
ol.upperroman {
|
||||
list-style: upper-roman;
|
||||
}
|
||||
|
||||
dl {
|
||||
margin-bottom: 15px;
|
||||
}
|
||||
|
||||
dd p {
|
||||
margin-top: 0px;
|
||||
}
|
||||
|
||||
dd ul, dd table {
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
dd {
|
||||
margin-top: 3px;
|
||||
margin-bottom: 10px;
|
||||
margin-left: 30px;
|
||||
}
|
||||
|
||||
dt:target, .highlighted {
|
||||
background-color: #fbe54e;
|
||||
}
|
||||
|
||||
dl.glossary dt {
|
||||
font-weight: bold;
|
||||
font-size: 1.1em;
|
||||
}
|
||||
|
||||
.field-list ul {
|
||||
margin: 0;
|
||||
padding-left: 1em;
|
||||
}
|
||||
|
||||
.field-list p {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.refcount {
|
||||
color: #060;
|
||||
}
|
||||
|
||||
.optional {
|
||||
font-size: 1.3em;
|
||||
}
|
||||
|
||||
.versionmodified {
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
.system-message {
|
||||
background-color: #fda;
|
||||
padding: 5px;
|
||||
border: 3px solid red;
|
||||
}
|
||||
|
||||
.footnote:target {
|
||||
background-color: #ffa
|
||||
}
|
||||
|
||||
.line-block {
|
||||
display: block;
|
||||
margin-top: 1em;
|
||||
margin-bottom: 1em;
|
||||
}
|
||||
|
||||
.line-block .line-block {
|
||||
margin-top: 0;
|
||||
margin-bottom: 0;
|
||||
margin-left: 1.5em;
|
||||
}
|
||||
|
||||
.guilabel, .menuselection {
|
||||
font-family: sans-serif;
|
||||
}
|
||||
|
||||
.accelerator {
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
.classifier {
|
||||
font-style: oblique;
|
||||
}
|
||||
|
||||
/* -- code displays --------------------------------------------------------- */
|
||||
|
||||
pre {
|
||||
overflow: auto;
|
||||
font-size: 1.1em;
|
||||
|
||||
}
|
||||
|
||||
td.linenos pre {
|
||||
padding: 5px 0px;
|
||||
border: 0;
|
||||
background-color: transparent;
|
||||
color: #aaa;
|
||||
}
|
||||
|
||||
table.highlighttable {
|
||||
margin-left: 0.5em;
|
||||
}
|
||||
|
||||
table.highlighttable td {
|
||||
padding: 0 0.5em 0 0.5em;
|
||||
}
|
||||
|
||||
tt.descname {
|
||||
background-color: transparent;
|
||||
font-weight: bold;
|
||||
font-size: 1.2em;
|
||||
}
|
||||
|
||||
tt.descclassname {
|
||||
background-color: transparent;
|
||||
}
|
||||
|
||||
tt.xref, a tt {
|
||||
background-color: transparent;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
h1 tt, h2 tt, h3 tt, h4 tt, h5 tt, h6 tt {
|
||||
background-color: transparent;
|
||||
}
|
||||
|
||||
.viewcode-link {
|
||||
float: right;
|
||||
}
|
||||
|
||||
.viewcode-back {
|
||||
float: right;
|
||||
font-family: sans-serif;
|
||||
}
|
||||
|
||||
div.viewcode-block:target {
|
||||
margin: -1px -10px;
|
||||
padding: 0 10px;
|
||||
}
|
||||
|
||||
/* -- math display ---------------------------------------------------------- */
|
||||
|
||||
img.math {
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
div.document div.math p {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
span.eqno {
|
||||
float: right;
|
||||
}
|
||||
|
||||
/* -- printout stylesheet --------------------------------------------------- */
|
||||
|
||||
@media print {
|
||||
div.document,
|
||||
div.documentwrapper,
|
||||
div.bodywrapper {
|
||||
margin: 0 !important;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
div.sphinxsidebar,
|
||||
div.related,
|
||||
div.footer,
|
||||
#top-link {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,52 @@
|
||||
---
|
||||
# Only the main Sass file needs front matter (the dashes are enough)
|
||||
---
|
||||
@charset "utf-8";
|
||||
|
||||
|
||||
|
||||
// Our variables
|
||||
$base-font-family: Helvetica, Arial, sans-serif;
|
||||
$base-font-size: 16px;
|
||||
$small-font-size: $base-font-size * 0.875;
|
||||
$base-line-height: 1.5;
|
||||
|
||||
$spacing-unit: 30px;
|
||||
|
||||
$text-color: #111;
|
||||
$background-color: #fdfdfd;
|
||||
$brand-color: #2a7ae2;
|
||||
|
||||
$grey-color: #828282;
|
||||
$grey-color-light: lighten($grey-color, 40%);
|
||||
$grey-color-dark: darken($grey-color, 25%);
|
||||
|
||||
// Width of the content area
|
||||
$content-width: 1340px;
|
||||
|
||||
$on-palm: 600px;
|
||||
$on-laptop: 800px;
|
||||
|
||||
|
||||
|
||||
// Using media queries with like this:
|
||||
// @include media-query($on-palm) {
|
||||
// .wrapper {
|
||||
// padding-right: $spacing-unit / 2;
|
||||
// padding-left: $spacing-unit / 2;
|
||||
// }
|
||||
// }
|
||||
@mixin media-query($device) {
|
||||
@media screen and (max-width: $device) {
|
||||
@content;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Import partials from `sass_dir` (defaults to `_sass`)
|
||||
@import
|
||||
"base",
|
||||
"layout",
|
||||
"syntax-highlighting"
|
||||
;
|
@ -0,0 +1,285 @@
|
||||
/*
|
||||
* nature.css_t
|
||||
* ~~~~~~~~~~~~
|
||||
*
|
||||
* Sphinx stylesheet -- nature theme.
|
||||
*
|
||||
* :copyright: Copyright 2007-2010 by the Sphinx team, see AUTHORS.
|
||||
* :license: BSD, see LICENSE for details.
|
||||
*
|
||||
*/
|
||||
|
||||
/* -- page layout ----------------------------------------------------------- */
|
||||
|
||||
body {
|
||||
font-family: Arial, sans-serif;
|
||||
font-size: 100%;
|
||||
/*background-color: #111;*/
|
||||
color: #555;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
div.documentwrapper {
|
||||
float: left;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
div.bodywrapper {
|
||||
margin: 0 0 0 230px;
|
||||
}
|
||||
|
||||
hr {
|
||||
border: 1px solid #B1B4B6;
|
||||
}
|
||||
|
||||
/*
|
||||
div.document {
|
||||
background-color: #eee;
|
||||
}
|
||||
*/
|
||||
|
||||
div.document {
|
||||
background-color: #ffffff;
|
||||
color: #3E4349;
|
||||
padding: 0 30px 30px 30px;
|
||||
font-size: 0.9em;
|
||||
}
|
||||
|
||||
div.footer {
|
||||
color: #555;
|
||||
width: 100%;
|
||||
padding: 13px 0;
|
||||
text-align: center;
|
||||
font-size: 75%;
|
||||
}
|
||||
|
||||
div.footer a {
|
||||
color: #444;
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
div.related {
|
||||
background-color: #6BA81E;
|
||||
line-height: 32px;
|
||||
color: #fff;
|
||||
text-shadow: 0px 1px 0 #444;
|
||||
font-size: 0.9em;
|
||||
}
|
||||
|
||||
div.related a {
|
||||
color: #E2F3CC;
|
||||
}
|
||||
|
||||
div.sphinxsidebar {
|
||||
font-size: 0.75em;
|
||||
line-height: 1.5em;
|
||||
}
|
||||
|
||||
div.sphinxsidebarwrapper{
|
||||
padding: 20px 0;
|
||||
}
|
||||
|
||||
div.sphinxsidebar h3,
|
||||
div.sphinxsidebar h4 {
|
||||
font-family: Arial, sans-serif;
|
||||
color: #222;
|
||||
font-size: 1.2em;
|
||||
font-weight: normal;
|
||||
margin: 0;
|
||||
padding: 5px 10px;
|
||||
background-color: #ddd;
|
||||
text-shadow: 1px 1px 0 white
|
||||
}
|
||||
|
||||
div.sphinxsidebar h4{
|
||||
font-size: 1.1em;
|
||||
}
|
||||
|
||||
div.sphinxsidebar h3 a {
|
||||
color: #444;
|
||||
}
|
||||
|
||||
|
||||
div.sphinxsidebar p {
|
||||
color: #888;
|
||||
padding: 5px 20px;
|
||||
}
|
||||
|
||||
div.sphinxsidebar p.topless {
|
||||
}
|
||||
|
||||
div.sphinxsidebar ul {
|
||||
margin: 10px 20px;
|
||||
padding: 0;
|
||||
color: #000;
|
||||
}
|
||||
|
||||
div.sphinxsidebar a {
|
||||
color: #444;
|
||||
}
|
||||
|
||||
div.sphinxsidebar input {
|
||||
border: 1px solid #ccc;
|
||||
font-family: sans-serif;
|
||||
font-size: 1em;
|
||||
}
|
||||
|
||||
div.sphinxsidebar input[type=text]{
|
||||
margin-left: 20px;
|
||||
}
|
||||
|
||||
/* -- body styles ----------------------------------------------------------- */
|
||||
|
||||
a {
|
||||
color: #005B81;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
a:hover {
|
||||
color: #E32E00;
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
div.document h1,
|
||||
div.document h2,
|
||||
div.document h3,
|
||||
div.document h4,
|
||||
div.document h5,
|
||||
div.document h6 {
|
||||
font-family: Arial, sans-serif;
|
||||
background-color: #BED4EB;
|
||||
font-weight: normal;
|
||||
color: #212224;
|
||||
margin: 30px 0px 10px 0px;
|
||||
padding: 5px 0 5px 10px;
|
||||
text-shadow: 0px 1px 0 white
|
||||
}
|
||||
|
||||
div.document h1 { border-top: 20px solid white; margin-top: 0; font-size: 200%; }
|
||||
div.document h2 { font-size: 150%; background-color: #C8D5E3; }
|
||||
div.document h3 { font-size: 120%; background-color: #D8DEE3; }
|
||||
div.document h4 { font-size: 110%; background-color: #D8DEE3; }
|
||||
div.document h5 { font-size: 100%; background-color: #D8DEE3; }
|
||||
div.document h6 { font-size: 100%; background-color: #D8DEE3; }
|
||||
|
||||
a.headerlink {
|
||||
color: #c60f0f;
|
||||
font-size: 0.8em;
|
||||
padding: 0 4px 0 4px;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
a.headerlink:hover {
|
||||
background-color: #c60f0f;
|
||||
color: white;
|
||||
}
|
||||
|
||||
div.document p, div.document dd, div.document li {
|
||||
line-height: 1.5em;
|
||||
}
|
||||
|
||||
div.admonition p.admonition-title + p {
|
||||
display: inline;
|
||||
}
|
||||
|
||||
div.highlight{
|
||||
background-color: white;
|
||||
}
|
||||
|
||||
div.note {
|
||||
background-color: #eee;
|
||||
border: 1px solid #ccc;
|
||||
}
|
||||
|
||||
div.seealso {
|
||||
background-color: #ffc;
|
||||
border: 1px solid #ff6;
|
||||
}
|
||||
|
||||
div.topic {
|
||||
background-color: #eee;
|
||||
}
|
||||
|
||||
div.warning {
|
||||
background-color: #ffe4e4;
|
||||
border: 1px solid #f66;
|
||||
}
|
||||
|
||||
p.admonition-title {
|
||||
display: inline;
|
||||
}
|
||||
|
||||
p.admonition-title:after {
|
||||
content: ":";
|
||||
}
|
||||
|
||||
pre {
|
||||
padding: 10px;
|
||||
background-color: White;
|
||||
color: #222;
|
||||
line-height: 1.2em;
|
||||
border: 1px solid #C6C9CB;
|
||||
font-size: 1.1em;
|
||||
margin: 1.5em 0 1.5em 0;
|
||||
-webkit-box-shadow: 1px 1px 1px #d8d8d8;
|
||||
-moz-box-shadow: 1px 1px 1px #d8d8d8;
|
||||
}
|
||||
|
||||
tt {
|
||||
background-color: #ecf0f3;
|
||||
color: #222;
|
||||
/* padding: 1px 2px; */
|
||||
font-size: 1.1em;
|
||||
font-family: monospace;
|
||||
}
|
||||
|
||||
.viewcode-back {
|
||||
font-family: Arial, sans-serif;
|
||||
}
|
||||
|
||||
div.viewcode-block:target {
|
||||
background-color: #f4debf;
|
||||
border-top: 1px solid #ac9;
|
||||
border-bottom: 1px solid #ac9;
|
||||
}
|
||||
|
||||
p {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
ul li dd {
|
||||
margin-top: 0;
|
||||
}
|
||||
|
||||
ul li dl {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
li dl dd {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
dd ul {
|
||||
padding-left: 0;
|
||||
}
|
||||
|
||||
li dd ul {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
table {
|
||||
margin-top: 10px;
|
||||
margin-bottom: 10px;
|
||||
border: 0;
|
||||
border-collapse: collapse;
|
||||
}
|
||||
|
||||
td[colspan]:not([colspan="1"]) {
|
||||
background: #eeeeee;
|
||||
}
|
||||
|
||||
thead {
|
||||
background: #eeeeee;
|
||||
}
|
||||
|
@ -0,0 +1,102 @@
|
||||
/** Common layout **/
|
||||
|
||||
html {
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
body {
|
||||
height: 100%;
|
||||
font-family: "Open Sans", Helvetica, Arial, sans-serif ! important;
|
||||
font-size: 12pt;
|
||||
margin: 0px;
|
||||
}
|
||||
|
||||
h1 {
|
||||
font-size: 20pt;
|
||||
}
|
||||
|
||||
a:link { color: #666;
|
||||
text-decoration: underline;
|
||||
}
|
||||
a:visited { color: #666; }
|
||||
a:hover { color: #000; }
|
||||
a:active { color: #000; }
|
||||
|
||||
a.anchor {
|
||||
display: block;
|
||||
position: relative;
|
||||
top: -50px;
|
||||
visibility: hidden;
|
||||
}
|
||||
|
||||
#page {
|
||||
min-height: 100%;
|
||||
margin-bottom: -32px; /* to make room for the footer */
|
||||
}
|
||||
|
||||
#wrapper {
|
||||
margin: auto;
|
||||
max-width: 1280px;
|
||||
padding-top: 40px;
|
||||
padding-bottom: 40px;
|
||||
padding-left: 20px;
|
||||
padding-right: 20px;
|
||||
}
|
||||
|
||||
#header
|
||||
{
|
||||
position: fixed;
|
||||
top: 0px;
|
||||
width: 100%;
|
||||
background-color: #000;
|
||||
min-height: 40px;
|
||||
}
|
||||
|
||||
.navButton {
|
||||
font-size: 20px;
|
||||
font-weight: bold;
|
||||
padding: 10px 20px 10px 20px;
|
||||
text-decoration: none ! important;
|
||||
}
|
||||
|
||||
#header .navButton {
|
||||
color: #fff ! important;
|
||||
}
|
||||
|
||||
#headerContent {
|
||||
/*
|
||||
color: #ccc;
|
||||
text-align: right;
|
||||
*/
|
||||
text-align: center;
|
||||
max-width: 1280px;
|
||||
margin: auto;
|
||||
min-height: 40px;
|
||||
line-height: 40px;
|
||||
}
|
||||
|
||||
#headerContent a:link,
|
||||
#headerContent a:visited,
|
||||
#headerContent a:hover,
|
||||
#headerContent a:active {
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
#footer
|
||||
{
|
||||
width: 100%;
|
||||
border-top: #666 1px solid;
|
||||
background-color: #aaa;
|
||||
height: 32px;
|
||||
}
|
||||
|
||||
#footerContent
|
||||
{
|
||||
font-size: 8pt;
|
||||
color: #fff;
|
||||
max-width: 1280px;
|
||||
margin: auto;
|
||||
text-align: center;
|
||||
height: 32px;
|
||||
line-height: 32px;
|
||||
}
|
@ -0,0 +1,30 @@
|
||||
---
|
||||
layout: null
|
||||
---
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
|
||||
<channel>
|
||||
<title>{{ site.title | xml_escape }}</title>
|
||||
<description>{{ site.description | xml_escape }}</description>
|
||||
<link>{{ site.url }}{{ site.baseurl }}/</link>
|
||||
<atom:link href="{{ "/feed.xml" | prepend: site.baseurl | prepend: site.url }}" rel="self" type="application/rss+xml"/>
|
||||
<pubDate>{{ site.time | date_to_rfc822 }}</pubDate>
|
||||
<lastBuildDate>{{ site.time | date_to_rfc822 }}</lastBuildDate>
|
||||
<generator>Jekyll v{{ jekyll.version }}</generator>
|
||||
{% for post in site.posts limit:10 %}
|
||||
<item>
|
||||
<title>{{ post.title | xml_escape }}</title>
|
||||
<description>{{ post.content | xml_escape }}</description>
|
||||
<pubDate>{{ post.date | date_to_rfc822 }}</pubDate>
|
||||
<link>{{ post.url | prepend: site.baseurl | prepend: site.url }}</link>
|
||||
<guid isPermaLink="true">{{ post.url | prepend: site.baseurl | prepend: site.url }}</guid>
|
||||
{% for tag in post.tags %}
|
||||
<category>{{ tag | xml_escape }}</category>
|
||||
{% endfor %}
|
||||
{% for cat in post.categories %}
|
||||
<category>{{ cat | xml_escape }}</category>
|
||||
{% endfor %}
|
||||
</item>
|
||||
{% endfor %}
|
||||
</channel>
|
||||
</rss>
|
@ -0,0 +1,23 @@
|
||||
---
|
||||
layout: default
|
||||
---
|
||||
|
||||
<div class="home">
|
||||
|
||||
<h1 class="page-heading">Posts</h1>
|
||||
|
||||
<ul class="post-list">
|
||||
{% for post in site.posts %}
|
||||
<li>
|
||||
<span class="post-meta">{{ post.date | date: "%b %-d, %Y" }}</span>
|
||||
|
||||
<h2>
|
||||
<a class="post-link" href="{{ post.url | prepend: site.baseurl }}">{{ post.title }}</a>
|
||||
</h2>
|
||||
</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
|
||||
<p class="rss-subscribe">subscribe <a href="{{ "/feed.xml" | prepend: site.baseurl }}">via RSS</a></p>
|
||||
|
||||
</div>
|
Loading…
Reference in New Issue