浏览代码

update documentation

Thomas Rabaix 14 年之前
父节点
当前提交
6c6fb91c23

+ 2 - 1
.gitignore

@@ -1,2 +1,3 @@
 .DS_Store
-phpunit.xml
+phpunit.xml
+Resources/doc/_build/*

+ 130 - 0
Resources/doc/Makefile

@@ -0,0 +1,130 @@
+# Makefile for Sphinx documentation
+#
+
+# You can set these variables from the command line.
+SPHINXOPTS    =
+SPHINXBUILD   = sphinx-build
+PAPER         =
+BUILDDIR      = _build
+
+# Internal variables.
+PAPEROPT_a4     = -D latex_paper_size=a4
+PAPEROPT_letter = -D latex_paper_size=letter
+ALLSPHINXOPTS   = -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) .
+
+.PHONY: help clean html dirhtml singlehtml pickle json htmlhelp qthelp devhelp epub latex latexpdf text man changes linkcheck doctest
+
+help:
+	@echo "Please use \`make <target>' where <target> is one of"
+	@echo "  html       to make standalone HTML files"
+	@echo "  dirhtml    to make HTML files named index.html in directories"
+	@echo "  singlehtml to make a single large HTML file"
+	@echo "  pickle     to make pickle files"
+	@echo "  json       to make JSON files"
+	@echo "  htmlhelp   to make HTML files and a HTML help project"
+	@echo "  qthelp     to make HTML files and a qthelp project"
+	@echo "  devhelp    to make HTML files and a Devhelp project"
+	@echo "  epub       to make an epub"
+	@echo "  latex      to make LaTeX files, you can set PAPER=a4 or PAPER=letter"
+	@echo "  latexpdf   to make LaTeX files and run them through pdflatex"
+	@echo "  text       to make text files"
+	@echo "  man        to make manual pages"
+	@echo "  changes    to make an overview of all changed/added/deprecated items"
+	@echo "  linkcheck  to check all external links for integrity"
+	@echo "  doctest    to run all doctests embedded in the documentation (if enabled)"
+
+clean:
+	-rm -rf $(BUILDDIR)/*
+
+html:
+	$(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html
+	@echo
+	@echo "Build finished. The HTML pages are in $(BUILDDIR)/html."
+
+dirhtml:
+	$(SPHINXBUILD) -b dirhtml $(ALLSPHINXOPTS) $(BUILDDIR)/dirhtml
+	@echo
+	@echo "Build finished. The HTML pages are in $(BUILDDIR)/dirhtml."
+
+singlehtml:
+	$(SPHINXBUILD) -b singlehtml $(ALLSPHINXOPTS) $(BUILDDIR)/singlehtml
+	@echo
+	@echo "Build finished. The HTML page is in $(BUILDDIR)/singlehtml."
+
+pickle:
+	$(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) $(BUILDDIR)/pickle
+	@echo
+	@echo "Build finished; now you can process the pickle files."
+
+json:
+	$(SPHINXBUILD) -b json $(ALLSPHINXOPTS) $(BUILDDIR)/json
+	@echo
+	@echo "Build finished; now you can process the JSON files."
+
+htmlhelp:
+	$(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) $(BUILDDIR)/htmlhelp
+	@echo
+	@echo "Build finished; now you can run HTML Help Workshop with the" \
+	      ".hhp project file in $(BUILDDIR)/htmlhelp."
+
+qthelp:
+	$(SPHINXBUILD) -b qthelp $(ALLSPHINXOPTS) $(BUILDDIR)/qthelp
+	@echo
+	@echo "Build finished; now you can run "qcollectiongenerator" with the" \
+	      ".qhcp project file in $(BUILDDIR)/qthelp, like this:"
+	@echo "# qcollectiongenerator $(BUILDDIR)/qthelp/Sonata-AdminBundle.qhcp"
+	@echo "To view the help file:"
+	@echo "# assistant -collectionFile $(BUILDDIR)/qthelp/Sonata-AdminBundle.qhc"
+
+devhelp:
+	$(SPHINXBUILD) -b devhelp $(ALLSPHINXOPTS) $(BUILDDIR)/devhelp
+	@echo
+	@echo "Build finished."
+	@echo "To view the help file:"
+	@echo "# mkdir -p $$HOME/.local/share/devhelp/Sonata-AdminBundle"
+	@echo "# ln -s $(BUILDDIR)/devhelp $$HOME/.local/share/devhelp/Sonata-AdminBundle"
+	@echo "# devhelp"
+
+epub:
+	$(SPHINXBUILD) -b epub $(ALLSPHINXOPTS) $(BUILDDIR)/epub
+	@echo
+	@echo "Build finished. The epub file is in $(BUILDDIR)/epub."
+
+latex:
+	$(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
+	@echo
+	@echo "Build finished; the LaTeX files are in $(BUILDDIR)/latex."
+	@echo "Run \`make' in that directory to run these through (pdf)latex" \
+	      "(use \`make latexpdf' here to do that automatically)."
+
+latexpdf:
+	$(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
+	@echo "Running LaTeX files through pdflatex..."
+	make -C $(BUILDDIR)/latex all-pdf
+	@echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex."
+
+text:
+	$(SPHINXBUILD) -b text $(ALLSPHINXOPTS) $(BUILDDIR)/text
+	@echo
+	@echo "Build finished. The text files are in $(BUILDDIR)/text."
+
+man:
+	$(SPHINXBUILD) -b man $(ALLSPHINXOPTS) $(BUILDDIR)/man
+	@echo
+	@echo "Build finished. The manual pages are in $(BUILDDIR)/man."
+
+changes:
+	$(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) $(BUILDDIR)/changes
+	@echo
+	@echo "The overview file is in $(BUILDDIR)/changes."
+
+linkcheck:
+	$(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) $(BUILDDIR)/linkcheck
+	@echo
+	@echo "Link check complete; look for any errors in the above output " \
+	      "or in $(BUILDDIR)/linkcheck/output.txt."
+
+doctest:
+	$(SPHINXBUILD) -b doctest $(ALLSPHINXOPTS) $(BUILDDIR)/doctest
+	@echo "Testing of doctests in the sources finished, look at the " \
+	      "results in $(BUILDDIR)/doctest/output.txt."

+ 73 - 0
Resources/doc/_exts/configurationblock.py

@@ -0,0 +1,73 @@
+from docutils.parsers.rst import Directive, directives
+from docutils import nodes
+from string import upper
+
+class configurationblock(nodes.General, nodes.Element):
+    pass
+
+class ConfigurationBlock(Directive):
+    has_content = True
+    required_arguments = 0
+    optional_arguments = 0
+    final_argument_whitespace = True
+    option_spec = {}
+    formats = {
+        'html':            'HTML',
+        'xml':             'XML',
+        'php':             'PHP',
+        'yaml':            'YAML',
+        'jinja':           'Twig',
+        'html+jinja':      'Twig',
+        'jinja+html':      'Twig',
+        'php+html':        'PHP',
+        'html+php':        'PHP',
+        'ini':             'INI',
+        'php-annotations': 'Annotations',
+    }
+
+    def run(self):
+        env = self.state.document.settings.env
+
+        node = nodes.Element()
+        node.document = self.state.document
+        self.state.nested_parse(self.content, self.content_offset, node)
+
+        entries = []
+        for i, child in enumerate(node):
+            if isinstance(child, nodes.literal_block):
+                # add a title (the language name) before each block
+                #targetid = "configuration-block-%d" % env.new_serialno('configuration-block')
+                #targetnode = nodes.target('', '', ids=[targetid])
+                #targetnode.append(child)
+
+                innernode = nodes.emphasis(self.formats[child['language']], self.formats[child['language']])
+
+                para = nodes.paragraph()
+                para += [innernode, child]
+
+                entry = nodes.list_item('')
+                entry.append(para)
+                entries.append(entry)
+
+        resultnode = configurationblock()
+        resultnode.append(nodes.bullet_list('', *entries))
+
+        return [resultnode]
+
+def visit_configurationblock_html(self, node):
+    self.body.append(self.starttag(node, 'div', CLASS='configuration-block'))
+
+def depart_configurationblock_html(self, node):
+    self.body.append('</div>\n')
+
+def visit_configurationblock_latex(self, node):
+    pass
+
+def depart_configurationblock_latex(self, node):
+    pass
+
+def setup(app):
+    app.add_node(configurationblock,
+                 html=(visit_configurationblock_html, depart_configurationblock_html),
+                 latex=(visit_configurationblock_latex, depart_configurationblock_latex))
+    app.add_directive('configuration-block', ConfigurationBlock)

二进制
Resources/doc/_exts/configurationblock.pyc


+ 221 - 0
Resources/doc/conf.py

@@ -0,0 +1,221 @@
+# -*- coding: utf-8 -*-
+#
+# Sonata - AdminBundle documentation build configuration file, created by
+# sphinx-quickstart on Sun May  1 16:09:38 2011.
+#
+# This file is execfile()d with the current directory set to its containing dir.
+#
+# Note that not all possible configuration values are present in this
+# autogenerated file.
+#
+# All configuration values have a default; values that are commented out
+# serve to show the default.
+
+import sys, os
+sys.path.append(os.path.abspath('_exts'))
+
+# If extensions (or modules to document with autodoc) are in another directory,
+# add these directories to sys.path here. If the directory is relative to the
+# documentation root, use os.path.abspath to make it absolute, like shown here.
+#sys.path.insert(0, os.path.abspath('.'))
+
+# -- General configuration -----------------------------------------------------
+
+# If your documentation needs a minimal Sphinx version, state it here.
+#needs_sphinx = '1.0'
+
+# Add any Sphinx extension module names here, as strings. They can be extensions
+# coming with Sphinx (named 'sphinx.ext.*') or your custom ones.
+extensions = ['configurationblock', 'sphinx.ext.intersphinx', 'sphinx.ext.todo', 'sphinx.ext.pngmath', 'sphinx.ext.ifconfig']
+
+# Add any paths that contain templates here, relative to this directory.
+templates_path = ['_templates']
+
+# The suffix of source filenames.
+source_suffix = '.rst'
+
+# The encoding of source files.
+#source_encoding = 'utf-8-sig'
+
+# The master toctree document.
+master_doc = 'index'
+
+# General information about the project.
+project = u'Sonata - AdminBundle'
+copyright = u'2011, Thomas Rabaix <thomas.rabaix@sonata-project.org>'
+
+# The version info for the project you're documenting, acts as replacement for
+# |version| and |release|, also used in various other places throughout the
+# built documents.
+#
+# The short X.Y version.
+version = '1.0.0-DEV'
+# The full version, including alpha/beta/rc tags.
+release = '1.0.0-DEV'
+
+# The language for content autogenerated by Sphinx. Refer to documentation
+# for a list of supported languages.
+#language = None
+
+# There are two options for replacing |today|: either, you set today to some
+# non-false value, then it is used:
+#today = ''
+# Else, today_fmt is used as the format for a strftime call.
+#today_fmt = '%B %d, %Y'
+
+# List of patterns, relative to source directory, that match files and
+# directories to ignore when looking for source files.
+exclude_patterns = ['_build']
+
+# The reST default role (used for this markup: `text`) to use for all documents.
+#default_role = None
+
+# If true, '()' will be appended to :func: etc. cross-reference text.
+#add_function_parentheses = True
+
+# If true, the current module name will be prepended to all description
+# unit titles (such as .. function::).
+#add_module_names = True
+
+# If true, sectionauthor and moduleauthor directives will be shown in the
+# output. They are ignored by default.
+#show_authors = False
+
+# The name of the Pygments (syntax highlighting) style to use.
+pygments_style = 'sphinx'
+
+# A list of ignored prefixes for module index sorting.
+#modindex_common_prefix = []
+
+
+# -- Options for HTML output ---------------------------------------------------
+
+# The theme to use for HTML and HTML Help pages.  See the documentation for
+# a list of builtin themes.
+html_theme = 'default'
+
+# Theme options are theme-specific and customize the look and feel of a theme
+# further.  For a list of options available for each theme, see the
+# documentation.
+#html_theme_options = {}
+
+# Add any paths that contain custom themes here, relative to this directory.
+#html_theme_path = []
+
+# The name for this set of Sphinx documents.  If None, it defaults to
+# "<project> v<release> documentation".
+#html_title = None
+
+# A shorter title for the navigation bar.  Default is the same as html_title.
+#html_short_title = None
+
+# The name of an image file (relative to this directory) to place at the top
+# of the sidebar.
+#html_logo = None
+
+# The name of an image file (within the static path) to use as favicon of the
+# docs.  This file should be a Windows icon file (.ico) being 16x16 or 32x32
+# pixels large.
+#html_favicon = None
+
+# Add any paths that contain custom static files (such as style sheets) here,
+# relative to this directory. They are copied after the builtin static files,
+# so a file named "default.css" will overwrite the builtin "default.css".
+html_static_path = ['_static']
+
+# If not '', a 'Last updated on:' timestamp is inserted at every page bottom,
+# using the given strftime format.
+#html_last_updated_fmt = '%b %d, %Y'
+
+# If true, SmartyPants will be used to convert quotes and dashes to
+# typographically correct entities.
+#html_use_smartypants = True
+
+# Custom sidebar templates, maps document names to template names.
+#html_sidebars = {}
+
+# Additional templates that should be rendered to pages, maps page names to
+# template names.
+#html_additional_pages = {}
+
+# If false, no module index is generated.
+#html_domain_indices = True
+
+# If false, no index is generated.
+#html_use_index = True
+
+# If true, the index is split into individual pages for each letter.
+#html_split_index = False
+
+# If true, links to the reST sources are added to the pages.
+#html_show_sourcelink = True
+
+# If true, "Created using Sphinx" is shown in the HTML footer. Default is True.
+#html_show_sphinx = True
+
+# If true, "(C) Copyright ..." is shown in the HTML footer. Default is True.
+#html_show_copyright = True
+
+# If true, an OpenSearch description file will be output, and all pages will
+# contain a <link> tag referring to it.  The value of this option must be the
+# base URL from which the finished HTML is served.
+#html_use_opensearch = ''
+
+# This is the file name suffix for HTML files (e.g. ".xhtml").
+#html_file_suffix = None
+
+# Output file base name for HTML help builder.
+htmlhelp_basename = 'Sonata-AdminBundledoc'
+
+
+# -- Options for LaTeX output --------------------------------------------------
+
+# The paper size ('letter' or 'a4').
+#latex_paper_size = 'letter'
+
+# The font size ('10pt', '11pt' or '12pt').
+#latex_font_size = '10pt'
+
+# Grouping the document tree into LaTeX files. List of tuples
+# (source start file, target name, title, author, documentclass [howto/manual]).
+latex_documents = [
+  ('index', 'Sonata-AdminBundle.tex', u'Sonata - AdminBundle Documentation',
+   u'Thomas Rabaix \\textless{}thomas.rabaix@sonata-project.org\\textgreater{}', 'manual'),
+]
+
+# The name of an image file (relative to this directory) to place at the top of
+# the title page.
+#latex_logo = None
+
+# For "manual" documents, if this is true, then toplevel headings are parts,
+# not chapters.
+#latex_use_parts = False
+
+# If true, show page references after internal links.
+#latex_show_pagerefs = False
+
+# If true, show URL addresses after external links.
+#latex_show_urls = False
+
+# Additional stuff for the LaTeX preamble.
+#latex_preamble = ''
+
+# Documents to append as an appendix to all manuals.
+#latex_appendices = []
+
+# If false, no module index is generated.
+#latex_domain_indices = True
+
+
+# -- Options for manual page output --------------------------------------------
+
+# One entry per manual page. List of tuples
+# (source start file, name, description, authors, manual section).
+man_pages = [
+    ('index', 'sonata-adminbundle', u'Sonata - AdminBundle Documentation',
+     [u'Thomas Rabaix <thomas.rabaix@sonata-project.org>'], 1)
+]
+
+
+# Example configuration for intersphinx: refer to the Python standard library.
+intersphinx_mapping = {'http://docs.python.org/': None}

+ 9 - 3
Resources/doc/index.rst

@@ -1,7 +1,12 @@
-Welcome to AdminBundle documentation
-==============================================
+.. Sonata - AdminBundle documentation master file, created by
+   sphinx-quickstart on Sun May  1 16:09:38 2011.
+   You can adapt this file completely to your liking, but it should at least
+   contain the root `toctree` directive.
 
-The ``AdminBundle`` provides a CRUD interface for a Doctrine entity.
+Welcome to Sonata - AdminBundle's documentation!
+================================================
+
+The ``AdminBundle`` provides a CRUD interface for model entity.
 
 Reference Guide
 ---------------
@@ -32,3 +37,4 @@ Tutorial
    tutorial/creating_your_first_admin_class/defining_crud_controller
    tutorial/creating_your_first_admin_class/defining_admin_class
    
+

+ 170 - 0
Resources/doc/make.bat

@@ -0,0 +1,170 @@
+@ECHO OFF
+
+REM Command file for Sphinx documentation
+
+if "%SPHINXBUILD%" == "" (
+	set SPHINXBUILD=sphinx-build
+)
+set BUILDDIR=_build
+set ALLSPHINXOPTS=-d %BUILDDIR%/doctrees %SPHINXOPTS% .
+if NOT "%PAPER%" == "" (
+	set ALLSPHINXOPTS=-D latex_paper_size=%PAPER% %ALLSPHINXOPTS%
+)
+
+if "%1" == "" goto help
+
+if "%1" == "help" (
+	:help
+	echo.Please use `make ^<target^>` where ^<target^> is one of
+	echo.  html       to make standalone HTML files
+	echo.  dirhtml    to make HTML files named index.html in directories
+	echo.  singlehtml to make a single large HTML file
+	echo.  pickle     to make pickle files
+	echo.  json       to make JSON files
+	echo.  htmlhelp   to make HTML files and a HTML help project
+	echo.  qthelp     to make HTML files and a qthelp project
+	echo.  devhelp    to make HTML files and a Devhelp project
+	echo.  epub       to make an epub
+	echo.  latex      to make LaTeX files, you can set PAPER=a4 or PAPER=letter
+	echo.  text       to make text files
+	echo.  man        to make manual pages
+	echo.  changes    to make an overview over all changed/added/deprecated items
+	echo.  linkcheck  to check all external links for integrity
+	echo.  doctest    to run all doctests embedded in the documentation if enabled
+	goto end
+)
+
+if "%1" == "clean" (
+	for /d %%i in (%BUILDDIR%\*) do rmdir /q /s %%i
+	del /q /s %BUILDDIR%\*
+	goto end
+)
+
+if "%1" == "html" (
+	%SPHINXBUILD% -b html %ALLSPHINXOPTS% %BUILDDIR%/html
+	if errorlevel 1 exit /b 1
+	echo.
+	echo.Build finished. The HTML pages are in %BUILDDIR%/html.
+	goto end
+)
+
+if "%1" == "dirhtml" (
+	%SPHINXBUILD% -b dirhtml %ALLSPHINXOPTS% %BUILDDIR%/dirhtml
+	if errorlevel 1 exit /b 1
+	echo.
+	echo.Build finished. The HTML pages are in %BUILDDIR%/dirhtml.
+	goto end
+)
+
+if "%1" == "singlehtml" (
+	%SPHINXBUILD% -b singlehtml %ALLSPHINXOPTS% %BUILDDIR%/singlehtml
+	if errorlevel 1 exit /b 1
+	echo.
+	echo.Build finished. The HTML pages are in %BUILDDIR%/singlehtml.
+	goto end
+)
+
+if "%1" == "pickle" (
+	%SPHINXBUILD% -b pickle %ALLSPHINXOPTS% %BUILDDIR%/pickle
+	if errorlevel 1 exit /b 1
+	echo.
+	echo.Build finished; now you can process the pickle files.
+	goto end
+)
+
+if "%1" == "json" (
+	%SPHINXBUILD% -b json %ALLSPHINXOPTS% %BUILDDIR%/json
+	if errorlevel 1 exit /b 1
+	echo.
+	echo.Build finished; now you can process the JSON files.
+	goto end
+)
+
+if "%1" == "htmlhelp" (
+	%SPHINXBUILD% -b htmlhelp %ALLSPHINXOPTS% %BUILDDIR%/htmlhelp
+	if errorlevel 1 exit /b 1
+	echo.
+	echo.Build finished; now you can run HTML Help Workshop with the ^
+.hhp project file in %BUILDDIR%/htmlhelp.
+	goto end
+)
+
+if "%1" == "qthelp" (
+	%SPHINXBUILD% -b qthelp %ALLSPHINXOPTS% %BUILDDIR%/qthelp
+	if errorlevel 1 exit /b 1
+	echo.
+	echo.Build finished; now you can run "qcollectiongenerator" with the ^
+.qhcp project file in %BUILDDIR%/qthelp, like this:
+	echo.^> qcollectiongenerator %BUILDDIR%\qthelp\Sonata-AdminBundle.qhcp
+	echo.To view the help file:
+	echo.^> assistant -collectionFile %BUILDDIR%\qthelp\Sonata-AdminBundle.ghc
+	goto end
+)
+
+if "%1" == "devhelp" (
+	%SPHINXBUILD% -b devhelp %ALLSPHINXOPTS% %BUILDDIR%/devhelp
+	if errorlevel 1 exit /b 1
+	echo.
+	echo.Build finished.
+	goto end
+)
+
+if "%1" == "epub" (
+	%SPHINXBUILD% -b epub %ALLSPHINXOPTS% %BUILDDIR%/epub
+	if errorlevel 1 exit /b 1
+	echo.
+	echo.Build finished. The epub file is in %BUILDDIR%/epub.
+	goto end
+)
+
+if "%1" == "latex" (
+	%SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex
+	if errorlevel 1 exit /b 1
+	echo.
+	echo.Build finished; the LaTeX files are in %BUILDDIR%/latex.
+	goto end
+)
+
+if "%1" == "text" (
+	%SPHINXBUILD% -b text %ALLSPHINXOPTS% %BUILDDIR%/text
+	if errorlevel 1 exit /b 1
+	echo.
+	echo.Build finished. The text files are in %BUILDDIR%/text.
+	goto end
+)
+
+if "%1" == "man" (
+	%SPHINXBUILD% -b man %ALLSPHINXOPTS% %BUILDDIR%/man
+	if errorlevel 1 exit /b 1
+	echo.
+	echo.Build finished. The manual pages are in %BUILDDIR%/man.
+	goto end
+)
+
+if "%1" == "changes" (
+	%SPHINXBUILD% -b changes %ALLSPHINXOPTS% %BUILDDIR%/changes
+	if errorlevel 1 exit /b 1
+	echo.
+	echo.The overview file is in %BUILDDIR%/changes.
+	goto end
+)
+
+if "%1" == "linkcheck" (
+	%SPHINXBUILD% -b linkcheck %ALLSPHINXOPTS% %BUILDDIR%/linkcheck
+	if errorlevel 1 exit /b 1
+	echo.
+	echo.Link check complete; look for any errors in the above output ^
+or in %BUILDDIR%/linkcheck/output.txt.
+	goto end
+)
+
+if "%1" == "doctest" (
+	%SPHINXBUILD% -b doctest %ALLSPHINXOPTS% %BUILDDIR%/doctest
+	if errorlevel 1 exit /b 1
+	echo.
+	echo.Testing of doctests in the sources finished, look at the ^
+results in %BUILDDIR%/doctest/output.txt.
+	goto end
+)
+
+:end

+ 42 - 14
Resources/doc/reference/architecture.rst

@@ -1,14 +1,14 @@
 Architecture
 ============
 
-The architecture of the bundle is mostly based off of the Django Admin Project,
+The architecture of the bundle is mostly based on the Django Admin Project,
 which is a truly great project. More information can be found at the
 `Django Project Website`_.
 
 The Admin Class
 ---------------
 
-The ``Admin`` class is the CRUD definition of one Doctrine entity. It contains
+The ``Admin`` class is the CRUD definition of one model. It contains
 all the configuration necessary to display a rich CRUD for the entity. From
 within an admin class, the following information can be defined:
 
@@ -26,12 +26,12 @@ within the first ``Admin`` class.
 The admin class is a service implementing the ``AdminInterface``, meaning that
 only required dependencies are injected:
 
-* ``ListBuilder``
-* ``FormBuildre``
-* ``DatagridBuilder``
-* ``Router``
-* ``Request``
-* ``EntityManager``
+* ``ListBuilder`` : build the list fields
+* ``FormContractor`` : construct the form using the Symfony ``FormBuilder``
+* ``DatagridBuilder`` : build the filter fields
+* ``Router`` : generate the different urls
+* ``Request`` 
+* ``ModelManager`` : Service which handle specific ORM code
 * ``Translator``
 
 
@@ -58,7 +58,7 @@ Here, the FOS' User Manager is injected into the Post service.
 Field Definition
 ----------------
 
-A field definition is a FieldDescription object. There is one definition per list
+A field definition is a ``FieldDescription`` object. There is one definition per list
 field.
 
 The definition contains:
@@ -70,15 +70,18 @@ The definition contains:
 * ``options``: Certain field types have additional options;
 
 Template Configuration
-~~~~~~~~~~~~~~~~~~~~~~
+-----------------------
 
 The current implementation uses Twig as the template engine. All templates
-are located in the Resources/views/CRUD directory of the bundle. The base
+are located in the ``Resources/views/CRUD`` directory of the bundle. The base
 template extends two layouts:
 
 * ``AdminBundle::standard_layout.twig``
 * ``AdminBundle::ajax_layout.twig``
 
+The base templates can be configured in the Service Container. So you can easily tweak
+the layout upon your requirements.
+
 Each field is rendered in three different ways and each has its own Twig
 template. For example, for a field with a ``text`` type, the following three
 templates will be used:
@@ -106,9 +109,34 @@ Obtaining an ``Admin`` Service
 ``Admin`` definition are accessible through the 'sonata.admin.pool' service or directly from the DIC.
 The ``Admin`` definitions are lazy loaded from the DIC to avoid overhead.
 
-Filter and Datagrid
--------------------
 
-todo ...
+Declaring a new Admin class
+---------------------------
+
+Once you have created an admin class, you must declare the class to use it. Like
+
+.. code-block:: xml
+
+    <!-- app/config/config.xml -->
+    <service id="sonata.news.admin.post" class="Sonata\NewsBundle\Admin\PostAdmin">
+
+        <tag name="sonata.admin" manager_type="orm" group="sonata_blog" label="post"/>
+
+        <argument />
+        <argument>Sonata\NewsBundle\Entity\Post</argument>
+        <argument>SonataNewsBundle:PostAdmin</argument>
+    </service>
+
+Or if you're using an YML configuration file,
+
+.. code-block:: yml
+
+    services:
+       sonata.news.admin.post:
+          class: Sonata\NewsBundle\Admin\PostAdmin
+          tags:
+            - { name: sonata.admin, manager_type: orm, group: sonata_blog, label: post }
+          arguments: [null, Sonata\NewsBundle\Entity\Post, SonataNewsBundle:PostAdmin]
+
 
 .. _`Django Project Website`: http://www.djangoproject.com/

+ 5 - 0
Resources/doc/reference/dashboard.rst

@@ -3,3 +3,8 @@ Dashboard
 
 The dashboard is the main landing page. For now the dashboard lists the
 different admin areas available.
+
+
+.. image:: ../images/dashboard.png 
+           :alt: Dashboard
+           :width: 50%

+ 57 - 33
Resources/doc/reference/filter_field_definition.rst

@@ -25,40 +25,13 @@ Example
 
         public function configureDatagridFilters(DatagridMapper $datagrid)
         {
-
-            $datagrid->add('with_open_comments', array(
-                'template' => 'SonataAdminBundle:CRUD:filter_callback.html.twig',
-                'type' => 'callback',
-                'filter_options' => array(
-                    'filter' => array($this, 'getWithOpenCommentFilter'),
-                    'field'  => array($this, 'getWithOpenCommentField')
-                )
-            ));
-        }
-
-        public function getWithOpenCommentFilter($queryBuilder, $alias, $field, $value)
-        {
-
-            if (!$value) {
-                return;
-            }
-
-            $queryBuilder->leftJoin(sprintf('%s.comments', $alias), 'c');
-            $queryBuilder->andWhere('c.status = :status');
-            $queryBuilder->setParameter('status', \Application\Sonata\NewsBundle\Entity\Comment::STATUS_MODERATE);
-        }
-
-        public function getWithOpenCommentField($filter)
-        {
-
-            return new \Symfony\Component\Form\CheckboxField(
-                $filter->getName(),
-                array()
-            );
+            // this is equivalent to :
+            $datagrid->add('title');
+            $datagrid->add('enabled');
+            $datagrid->add('tags', array('filter_field_options' => array('expanded' => true, 'multiple' => true))
         }
     }
 
-
 Types available
 ---------------
 
@@ -76,7 +49,58 @@ if no type is set, the Admin class will use the one set in the doctrine mapping
 Tweak it!
 ---------
 
-- It is possible to tweak the default template by setting a template key in the
+- It is possible to tweak the default template by setting a ``template`` key in the 
+  options array.
 - If the project required specific behaviors, they can be implemented in the
-configureFilterFields() method.
+  ``configureFilterFields()`` method.
+  
+Advanced usage
+--------------
 
+If you want to create a custom callback filter, this is how to do. ``getWithOpenCommentField`` and
+``getWithOpenCommentFilter``  are callback method used to define the field type and how to filter 
+the provided value.
+
+.. code-block:: php
+
+    <?php
+    namespace Sonata\NewsBundle\Admin;
+
+    use Sonata\AdminBundle\Datagrid\DatagridMapper;
+    use Sonata\AdminBundle\Admin\Admin;
+    use Application\Sonata\NewsBundle\Entity\Comment;
+    
+    class PostAdmin extends Admin
+    {
+        protected $filter = array(
+            'title',
+            'enabled',
+            'tags' => array('filter_field_options' => array('expanded' => true, 'multiple' => true))
+        );
+
+        public function configureDatagridFilters(DatagridMapper $datagrid)
+        {
+            $datagrid->add('with_open_comments', array(
+                'template' => 'SonataAdminBundle:CRUD:filter_callback.html.twig',
+                'type' => 'callback',
+                'filter_options' => array(
+                    'filter' => array($this, 'getWithOpenCommentFilter'),
+                    'type'   => 'checkbox'
+                ),
+                'filter_field_options' => array(
+                    'required' => false
+                )
+            ));
+        }
+
+        public function getWithOpenCommentFilter($queryBuilder, $alias, $field, $value)
+        {
+            if (!$value) {
+                return;
+            }
+
+            $queryBuilder->leftJoin(sprintf('%s.comments', $alias), 'c');
+            $queryBuilder->andWhere('c.status = :status');
+            $queryBuilder->setParameter('status', Comment::STATUS_MODERATE);
+        }
+    }

+ 104 - 19
Resources/doc/reference/form_field_definition.rst

@@ -1,8 +1,6 @@
 Form field definition
 =====================
 
-These fields are used to display inside the edit form.
-
 Example
 -------
 
@@ -22,25 +20,26 @@ Example
             'title',
             'abstract',
             'content',
-            'tags' => array('form_field_options' => array('expanded' => true)),
-            'comments_close_at',
-            'comments_enabled',
-            'comments_default_status'
         );
 
         public function configureFormFields(FormMapper $form)
         {
-            $form->add('author', array(), array('edit' => 'list'));
-            $form->add('title');
-
-            // add comments_default_status by configuring an internal FieldDescription
-            $form->add('comments_default_status', array('choices' => Comment::getStatusList()), array('type' => 'choice'));
-
-            // or by creating the FormField
-            $form->add(new \Symfony\Component\Form\ChoiceField('comments_default_status', array('choices' => Comment::getStatusList())));
+            // equivalent to :
+            $formMapper
+              ->add('author', array(), array('edit' => 'list'))
+              ->add('enabled')
+              ->add('title')
+              ->add('abtract', array(), array('required' => false))
+              ->add('content');
         }
     }
 
+.. note::
+
+    By default, the form framework always set ``required=true`` for field. This can be an issue for
+    HTML5 browsers as they provide client side validation.
+
+
 Types available
 ---------------
 
@@ -59,10 +58,96 @@ Types available
 
 if no type is set, the Admin class will use the one set in the doctrine mapping definition.
 
-Tweak it!
----------
+Advanced Usage : File Management
+--------------------------------
+
+If you want to use custom type from the Form framework you must used the ``addType`` method. (The ``add`` method uses
+the information provided by the model definition).
+
+.. code-block:: php
+
+    <?php
+    namespace Sonta\NewsBundle\Admin;
+
+    use Sonata\AdminBundle\Form\FormMapper;
+    use Sonata\AdminBundle\Admin\Admin;
+
+    class MediaAdmin extends Admin
+    {
+        public function configureFormFields(FormMapper $form)
+        {
+            $formMapper
+                ->add('name', array('required' => false))
+                ->add('enabled', array('required' => false))
+                ->add('authorName', array('required' => false))
+                ->add('cdnIsFlushable', array('required' => false))
+                ->add('description', array('required' => false))
+                ->add('copyright', array('required' => false))
+                // add a custom type, using the native form factory
+                ->addType('binaryContent', 'file', array('type' => false, 'required' => false));
+        }
+  }
+
+.. note::
+
+    By setting ``type=false`` in the file definition, the Form framework will provide an instance of
+    ``UploadedFile`` for the ``Media::setBinaryContent`` method. Otherwise, the full path will be provided.
+
+
+
+
+Advanced Usage : Many-to-one
+----------------------------
 
-- It is possible to tweak the default template by setting a template key in the
-- If the project required specific behaviors, they can be implemented in the
-configureFormFields() method.
+If you have many ``Post`` linked to one ``User``, then the ``Post`` form should display a ``User`` field. 
+The AdminBundle provides 3 edit options :
 
+ - ``standard`` : default value, the user list is set in a select widget
+ - ``list`` : the user list is set in a model where you can search and select a user
+ 
+In both case, you can create a new ``User`` by clicking on the "+" icon.
+
+The last option, is ``inline`` this option embed the ``User`` form into the ``Post`` Form. This option is
+great for One-to-one, or if your want to allow the user to edit the ``User`` information.
+
+.. code-block:: php
+
+    <?php
+    namespace Sonata\NewsBundle\Admin;
+
+    class PostAdmin extends Admin
+    {
+        protected $form = array(
+            'author'  => array('edit' => 'list'),
+        );
+    }
+
+Advanced Usage : One-to-many
+----------------------------
+
+Let's say you have a ``Gallery`` links to some ``Media`` with a join table ``galleryHasMedias``. You
+can easily add new ``galleryHasMedias`` row by defining the different options :
+
+  - ``edit`` : ``inline|standard``, the inline mode allows you to add new rows
+  - ``inline`` : ``table|standard``, the fields are displayed into table
+  - ``sortable`` : if the model has an position field, you can enable a drag and drop sortable effect by setting ``sortable=field_name``
+
+
+.. code-block:: php
+
+    <?php
+    namespace Sonata\MediaBundle\Admin;
+
+    use Sonata\AdminBundle\Admin\Admin;
+
+    class GalleryAdmin extends Admin
+    {
+        protected $form = array(
+            'name',
+            'galleryHasMedias' => array(
+                'edit' => 'inline',
+                'inline' => 'table',
+                'sortable' => 'position'
+            ),
+        );
+    }

+ 13 - 38
Resources/doc/reference/installation.rst

@@ -1,12 +1,10 @@
 Installation
 ============
 
-Make sure you have ``Sonata`` and ``Knplabs`` exists, if not create them::
+Download bundles
+----------------
 
-  mkdir src/Sonata
-  mkdir src/Knplabs
-
-To begin, add the dependent bundles to the ``src/`` directory. If using
+To begin, add the dependent bundles to the ``src/`` directory. If you are using
 git, you can add them as submodules::
 
   git submodule add git@github.com:sonata-project/jQueryBundle.git src/Sonata/jQueryBundle
@@ -14,6 +12,16 @@ git, you can add them as submodules::
   git submodule add git@github.com:sonata-project/AdminBundle.git src/Sonata/AdminBundle
   git submodule add git@github.com:sonata-project/MenuBundle.git src/Knplabs/Bundle/MenuBundle
 
+If you are not using git, you will have to download them :
+
+  - https://github.com/sonata-project/jQueryBundle/archives/master
+  - https://github.com/sonata-project/BluePrintBundle/archives/master
+  - https://github.com/sonata-project/AdminBundle/archives/master
+  - https://github.com/sonata-project/MenuBundle/archives/master
+  
+Configuration
+-------------
+  
 Next, be sure to enable the bundles in your application kernel:
 
 .. code-block:: php
@@ -39,14 +47,10 @@ Next, be sure to enable the bundles in your application kernel:
       );
   }
 
-Configuration
--------------
 
 The bundle also contains several routes. Import them by adding the following
 code to your application's routing file:
 
-- Add the AdminBundle's routing definition
-
 .. code-block:: yaml
 
     # app/config/routing.yml
@@ -68,32 +72,3 @@ At this point you can access to the dashboard with the url: ``http://yoursite.lo
     the above configuration and routing will actually be placed in those
     files, with the correct format (i.e. XML or PHP).
 
-
-Declaring new Entity
---------------------
-
-Once you have created an admin class, you must declare the class to use it. Like ::
-
-.. code-block:: xml
-
-    # app/config/config.xml
-
-    <service id="sonata.news.admin.post" class="Sonata\NewsBundle\Admin\PostAdmin">
-
-        <tag name="sonata.admin" manager_type="orm" group="sonata_blog" label="post"/>
-
-        <argument />
-        <argument>Sonata\NewsBundle\Entity\Post</argument>
-        <argument>SonataNewsBundle:PostAdmin</argument>
-    </service>
-
-Or if you're using an YML configuration file,
-
-.. code-block:: yml
-
-    services:
-       sonata.news.admin.post:
-          class: Sonata\NewsBundle\Admin\PostAdmin
-          tags:
-            - { name: sonata.admin, manager_type: orm, group: sonata_blog, label: post }
-          arguments: [null, Sonata\NewsBundle\Entity\Post, SonataNewsBundle:PostAdmin]

+ 38 - 14
Resources/doc/reference/list_field_definition.rst

@@ -17,15 +17,19 @@ Example
     class PostAdmin extends Admin
     {
         protected $list = array(
-            'title'   => array(),
-            'enabled' => array('type' => 'boolean'),
-            'tags'    => array(),
-            'summary' => array()
+            'title' => array('identifier' => true), // add edit link
+            'enabled',
+            'tags',
+            'summary',
         );
 
         protected function configureListFields(ListMapper $list) // optional
         {
-            $list->get('summary')->setTemplate('NewsBundle:NewsAdmin:list_summary.twig');
+            // or equivalent to :
+            $list->add('title', array('identifier' => true));
+            $list->add('enabled');
+            $list->add('tags);
+            $list->add('summary');
         }
     }
 
@@ -40,7 +44,7 @@ Types available
 The most important option for each field is the ``type``: The available
 types include:
 
-* boolean
+* boolean 
 * datetime
 * decimal
 * identifier
@@ -67,10 +71,11 @@ You can set actions for each items in list by adding in $list, the '_action' fie
       )
     )
 
-Edit and delete actions are available in default configuration. You can add your own! Default template file is :
-    SonataAdminBundle:CRUD:list__action_[ACTION_NAME].html.twig
+Edit and delete actions are available in default configuration. You can add your own! Default template 
+file is : ``SonataAdminBundle:CRUD:list__action_[ACTION_NAME].html.twig``
   
 But you can specify yours by setup 'template' option like :
+
 .. code-block:: php
 
     '_action' => array(
@@ -80,12 +85,31 @@ But you can specify yours by setup 'template' option like :
       )
     )
 
-Tweak it!
----------
+Advance Usage
+-------------
+
+If you need a specific layout for a row cell, you can define a custom template
+
+
+.. code-block:: php
+
+    class MediaAdmin extends Admin
+    {
+        protected $list = array(
+            'custom' => array('template' => 'SonataMediaBundle:MediaAdmin:list_custom.html.twig', 'type' => 'string'),
+            'enabled',
+        )
+    }
+
+The related template :
 
-It is possible to change the default template by setting a template key in the
-definition.
+.. code-block:: jinja
 
-- if the identifier key is set, then the field will be encapsulate by a link to
-the edit action
+    {% extends 'SonataAdminBundle:CRUD:base_list_field.html.twig' %}
 
+    {% block field%}
+        <div>
+            <strong>{{ object.name }}</strong> <br />
+            {{ object.providername}} : {{ object.width }}x{{ object.height }} <br />
+        </div>
+    {% endblock %}

+ 1 - 1
Resources/doc/reference/routing.rst

@@ -13,7 +13,7 @@ Routing Definition
 ------------------
 
 You can set a ``baseRouteName`` property inside your ``Admin`` class, which
-represents the route prefix.
+represents the route prefix.  
 
 .. code-block:: php
 

+ 72 - 8
Resources/doc/tutorial/creating_your_first_admin_class/defining_admin_class.rst

@@ -15,6 +15,7 @@ First, you need to create an Admin/PostAdmin.php file
 
 .. code-block:: php
 
+    <?php
     namespace Sonata\NewsBundle\Admin;
 
     use Sonata\AdminBundle\Admin\Admin;
@@ -22,9 +23,41 @@ First, you need to create an Admin/PostAdmin.php file
     use Sonata\AdminBundle\Datagrid\DatagridMapper;
     use Sonata\AdminBundle\Datagrid\ListMapper;
 
+    use Sonata\NewsBundle\Entity\Comment;
+
     class PostAdmin extends Admin
     {
+        protected $list = array(
+            'title' => array('identifier' => true),
+            'author',
+            'enabled',
+            'commentsEnabled',
+        );
+
+        protected $form = array(
+            'author'  => array('edit' => 'list'),
+            'enabled' => array('form_field_options' => array('required' => false)),
+            'title',
+            'abstract',
+            'content',
+            'tags'     => array('form_field_options' => array('expanded' => true)),
+            'commentsCloseAt',
+            'commentsEnabled' => array('form_field_options' => array('required' => false)),
+        );
+
+        protected $filter = array(
+            'title',
+            'enabled',
+            'tags' => array('filter_field_options' => array('expanded' => true, 'multiple' => true))
+        );
 
+        public function configureFormFields(FormMapper $formMapper)
+        {
+            $formMapper
+              ->add('author')
+              ->add('image', array(), array('edit' => 'list', 'link_parameters' => array('context' => 'news')))
+              ->add('commentsDefaultStatus', array('choices' => Comment::getStatusList()), array('type' => 'choice'));
+        }
     }
 
 Secondly, register the PostAdmin class inside the DIC in your config.xml file.
@@ -32,7 +65,6 @@ Secondly, register the PostAdmin class inside the DIC in your config.xml file.
 .. code-block:: xml
 
     <service id="sonata.news.admin.post" class="Sonata\NewsBundle\Admin\PostAdmin">
-
         <tag name="sonata.admin" manager_type="orm" group="sonata_blog" label="post"/>
 
         <argument/>
@@ -42,7 +74,7 @@ Secondly, register the PostAdmin class inside the DIC in your config.xml file.
 
 Or if you're using an YML configuration file,
 
-.. code-block:: yml
+.. code-block:: yaml
 
     services:
        sonata.news.admin.post:
@@ -63,6 +95,18 @@ You can specify which field you want displayed for each action (list, form and f
 
 .. code-block:: php
 
+    <?php
+    namespace Sonata\NewsBundle\Admin;
+
+    use Sonata\AdminBundle\Admin\Admin;
+    use Sonata\AdminBundle\Form\FormMapper;
+    use Sonata\AdminBundle\Datagrid\DatagridMapper;
+    use Sonata\AdminBundle\Datagrid\ListMapper;
+
+    use Knplabs\Bundle\MenuBundle\MenuItem;
+
+    use Application\Sonata\NewsBundle\Entity\Comment;
+    
     class PostAdmin extends Admin
     {
        protected $list = array(
@@ -95,17 +139,17 @@ Now the different CRUD interfaces will look nicer!
 So same goes for the TagAdmin and CommentAdmin class.
 
 Tweak the TagAdmin class
---------
+------------------------
 
 .. code-block:: php
 
+    <?php
     namespace Sonata\NewsBundle\Admin;
 
     use Sonata\AdminBundle\Admin\Admin;
 
     class TagAdmin extends Admin
     {
-
         protected $list = array(
             'name' => array('identifier' => true),
             'slug',
@@ -113,25 +157,36 @@ Tweak the TagAdmin class
         );
 
         protected $form = array(
+            'id',
             'name',
             'enabled'
         );
+
+        protected $filter = array(
+            'name'
+        );
     }
 
 Tweak the CommentAdmin class
-------------
+----------------------------
 
 .. code-block:: php
 
+    <?php
     namespace Sonata\NewsBundle\Admin;
 
     use Sonata\AdminBundle\Admin\Admin;
+    use Sonata\AdminBundle\Form\FormMapper;
+    use Sonata\AdminBundle\Datagrid\DatagridMapper;
+    use Sonata\AdminBundle\Datagrid\ListMapper;
+
+    use Sonata\NewsBundle\Entity\Comment;
 
     class CommentAdmin extends Admin
     {
         protected $list = array(
             'name' => array('identifier' => true),
-            'getStatusCode' => array('label' => 'status_code'),
+            'getStatusCode' => array('label' => 'status_code', 'type' => 'string', 'sortable' => 'status'),
             'post',
             'email',
             'url',
@@ -143,7 +198,16 @@ Tweak the CommentAdmin class
             'email',
             'url',
             'message',
-            'post',
-            'status' => array('type' => 'choice'),
         );
+
+        protected $filter = array(
+            'name',
+            'email',
+            'message'
+        );
+
+        public function configureFormFields(FormMapper $form)
+        {
+            $form->add('status', array('choices' => Comment::getStatusList()), array('type' => 'choice'));
+        }
     }

+ 19 - 9
Resources/doc/tutorial/creating_your_first_admin_class/defining_crud_controller.rst

@@ -1,29 +1,37 @@
 Defining the CRUD controller
-===========================
+============================
 
 A crud controller class is just an empty class with no methods. However, you can easily add here
 new action or overwrite the default CRUD actions.
 
-Just create 3 files inside the Controller directory
+.. note::
+  
+    The controller declaration is optional, if none is defined, then the ``AdminBundle`` will use
+    the ``CRUDController``.
 
+Just create 3 files inside the Controller directory
 
-- CommendAdminController.php
+CommendAdminController
+~~~~~~~~~~~~~~~~~~~~~~
 
-..
+.. code-block:: php
 
+    <?php
     namespace Sonata\NewsBundle\Controller;
 
     use Sonata\AdminBundle\Controller\CRUDController as Controller;
     
-    class TagAdminController extends Controller
+    class CommentAdminController extends Controller
     {
 
     }
 
-- PostAdminController.php
+PostAdminController
+~~~~~~~~~~~~~~~~~~~
 
-..
+.. code-block:: php
 
+    <?php
     namespace Sonata\NewsBundle\Controller;
 
     use Sonata\AdminBundle\Controller\CRUDController as Controller;
@@ -33,10 +41,12 @@ Just create 3 files inside the Controller directory
 
     }
 
-- TagAdminController.php
+TagAdminController
+~~~~~~~~~~~~~~~~~~
 
-..
+.. code-block:: php
 
+    <?php
     namespace Sonata\NewsBundle\Controller;
 
     use Sonata\AdminBundle\Controller\CRUDController as Controller;

+ 148 - 238
Resources/doc/tutorial/creating_your_first_admin_class/defining_entities.rst

@@ -1,47 +1,39 @@
-Defining CRUD controller
-========================
+Defining Entities
+=================
 
 This tutorial use the verbose xml definition, the other alternative will be to use the annotation driver.
 
+
+
 Model definition
 ----------------
 
-- Comment
+Comment
+~~~~~~~
 
-..
+.. code-block:: php
 
-    class BaseComment
+    class Comment
     {
         const STATUS_MODERATE   = 2;
         const STATUS_VALID   = 1;
         const STATUS_INVALID = 0;
 
         protected $name;
-
         protected $email;
-
         protected $url;
-
         protected $message;
-
         protected $created_at;
-
         protected $updated_at;
-
         protected $status = self::STATUS_VALID;
-
         protected $post;
 
         public static function getStatusList()
         {
             return array(
-
                 self::STATUS_MODERATE => 'moderate',
-
                 self::STATUS_INVALID => 'invalid',
-
                 self::STATUS_VALID   => 'valid',
-
             );
         }
 
@@ -55,49 +47,33 @@ Model definition
         {
             $object->setUpdatedAt(new \DateTime);
         }
-
     }
-    
-- Post
 
-..
+Post
+~~~~
 
-    class BasePost
-    {
+.. code-block:: php
 
+    class Post
+    {
         protected $title;
-
         protected $slug;
-
         protected $abstract;
-
         protected $content;
-
         protected $tags;
-
         protected $comments;
-
         protected $enabled;
-
         protected $publication_date_start;
-
         protected $created_at;
-
         protected $updated_at;
-
         protected $comments_enabled = true;
-
         protected $comments_close_at;
-
         protected $comments_default_status;
 
         public function __construct()
         {
-
             $this->tags     = new \Doctrine\Common\Collections\ArrayCollection;
-
             $this->comments = new \Doctrine\Common\Collections\ArrayCollection;
-            
         }
 
         public function preInsert($object)
@@ -112,26 +88,20 @@ Model definition
         }
     }
     
-- Tag
+Tag
+~~~
 
-..
+.. code-block:: php
 
-    class BaseTag
+    class Tag
     {
-
         protected $name;
-
         protected $slug;
-
         protected $created_at;
-
         protected $updated_at;
-
         protected $enabled;
-
         protected $posts;
 
-
         public function preInsert($object)
         {
             $object->setCreatedAt(new \DateTime);
@@ -144,206 +114,146 @@ Model definition
         }
     }
 
+
 Mapping definition
 ------------------
 
+Comment
+~~~~~~~
 
-- Comment
-
-..
+.. code-block:: xml
 
-  <?xml version="1.0" encoding="utf-8"?>
-
-  <doctrine-mapping xmlns="http://doctrine-project.org/schemas/orm/doctrine-mapping" xsi="http://www.w3.org/2001/XMLSchema-instance" schemaLocation="http://doctrine-project.org/schemas/orm/doctrine-mapping http://doctrine-project.org/schemas/orm/doctrine-mapping.xsd">
-  
-      <entity name="Application\Sonata\NewsBundle\Entity\Comment" table="news__comment" repository-class="Application\Sonata\NewsBundle\Entity\CommentRepository">
-
-          <id name="id" type="integer" column="id">
-              <generator strategy="AUTO"/>
-          </id>
+    <?xml version="1.0" encoding="utf-8"?>
+    <doctrine-mapping xmlns="http://doctrine-project.org/schemas/orm/doctrine-mapping" xsi="http://www.w3.org/2001/XMLSchema-instance" schemaLocation="http://doctrine-project.org/schemas/orm/doctrine-mapping http://doctrine-project.org/schemas/orm/doctrine-mapping.xsd">
+        <entity name="Sonata\NewsBundle\Entity\Comment" table="news__comment">
+            <id name="id" type="integer" column="id">
+                <generator strategy="AUTO"/>
+            </id>
          
-          <field name="name"              type="string"       column="name"          />
-
-          <field name="url"               type="string"       column="url"           />
-
-          <field name="email"             type="string"       column="email"           />
-
-          <field name="message"           type="text"         column="message"       />
-
-          <field name="status"            type="integer"      column="status"        default="false" />
-
-          <field name="created_at"    type="datetime"   column="created_at" />
-
-          <field name="updated_at"    type="datetime"   column="updated_at" />
-
-          <lifecycle-callbacks>
-
-            <lifecycle-callback type="prePersist" method="prePersist"/>
-
-            <lifecycle-callback type="preUpdate" method="preUpdate"/>
-
-          </lifecycle-callbacks>
-
-          <many-to-one field="post" target-entity="Application\Sonata\NewsBundle\Entity\Post">
-
-             <join-column name="post_id" referenced-column-name="id" />
-
-          </many-to-one>
-
-      </entity>
-    
-  </doctrine-mapping>
-
-
-- Post
-
-..
-
-  <?xml version="1.0" encoding="utf-8"?>
-
-  <doctrine-mapping xmlns="http://doctrine-project.org/schemas/orm/doctrine-mapping" xsi="http://www.w3.org/2001/XMLSchema-instance" schemaLocation="http://doctrine-project.org/schemas/orm/doctrine-mapping http://doctrine-project.org/schemas/orm/doctrine-mapping.xsd">
-
-      <entity name="Application\Sonata\NewsBundle\Entity\Post" table="news__post" repository-class="Application\Sonata\NewsBundle\Entity\PostRepository">
-
-          <id name="id" type="integer" column="id">
-              <generator strategy="AUTO"/>
-          </id>
-
-          <field name="title"             type="string"       column="title"           />
-
-          <field name="abstract"          type="text"         column="abstract"           />
-
-          <field name="content"           type="text"         column="content"           />
-
-          <field name="enabled"           type="boolean"      column="enabled"        default="false" />
-
-          <field name="slug"              type="string"      column="slug" />
-
-          <field name="publication_date_start"   type="datetime"   column="publication_date_start"    nullable="true"/>
-
-          <field name="comments_enabled"    type="boolean"   column="comments_enabled" default="true"/>
-
-          <field name="comments_close_at"   type="datetime"  column="comments_close_at" nullable="true"/>
-
-          <field name="comments_default_status"   type="integer"  column="comments_default_status" nullable="false"/>
-
-          <field name="created_at"    type="datetime"   column="created_at" />
-
-          <field name="updated_at"    type="datetime"   column="updated_at" />
-
-          <lifecycle-callbacks>
-
-              <lifecycle-callback type="prePersist" method="prePersist"/>
-
-              <lifecycle-callback type="preUpdate" method="preUpdate"/>
-
-          </lifecycle-callbacks>
-
-          <many-to-many
-              field="tags"
-              target-entity="Application\Sonata\NewsBundle\Entity\Tag"
-              inversed-by="posts"
-              fetch="EAGER"
-              >
-
-              <cascade>
-
-                  <cascade-persist />
-
-                  <!--<cascade-merge />-->
-
-                  <!--<cascade-remove />-->
-
-                  <!--<cascade-refresh />-->
-
-              </cascade>
-
-              <join-table name="news__post_tag">
-
-                  <join-columns>
-
-                      <join-column name="post_id" referenced-column-name="id"/>
-
-                  </join-columns>
-
-                  <inverse-join-columns>
-
-                      <join-column name="tag_id" referenced-column-name="id"/>
-
-                  </inverse-join-columns>
-
-              </join-table>
-
-          </many-to-many>
-
-          <one-to-many
-              field="comments"
-              target-entity="Application\Sonata\NewsBundle\Entity\Comment"
-              mapped-by="post">
-
-              <cascade>
-
-                  <cascade-persist/>
-
-              </cascade>
-
-              <join-columns>
-
-                  <join-column name="id" referenced-column-name="post_id" />
-
-              </join-columns>
-
-              <order-by>
-
-                  <order-by-field name="created_at" direction="DESC" />
-
-              </order-by>
-
-          </one-to-many>
-
-      </entity>
-
-  </doctrine-mapping>
-
-
-- Comment
-
-.. 
-
-  <?xml version="1.0" encoding="utf-8"?>
-
-  <doctrine-mapping xmlns="http://doctrine-project.org/schemas/orm/doctrine-mapping" xsi="http://www.w3.org/2001/XMLSchema-instance" schemaLocation="http://doctrine-project.org/schemas/orm/doctrine-mapping http://doctrine-project.org/schemas/orm/doctrine-mapping.xsd">
-
-      <entity name="Application\Sonata\NewsBundle\Entity\Tag" table="news__tag" repository-class="Application\Sonata\NewsBundle\Entity\TagRepository">
-
-          <id name="id" type="integer" column="id">
-              <generator strategy="AUTO"/>
-          </id>
-
-          <field name="name"          type="string"       column="title"           />
-
-          <field name="enabled"       type="boolean"      column="enabled"        default="false" />
-
-          <field name="slug"          type="string"      column="slug"    />
-
-          <field name="created_at"    type="datetime"   column="created_at" />
-
-          <field name="updated_at"    type="datetime"   column="updated_at" />
-
-          <lifecycle-callbacks>
-
+            <field name="name"              type="string"       column="name"          />
+            <field name="url"               type="string"       column="url"           />
+            <field name="email"             type="string"       column="email"           />
+            <field name="message"           type="text"         column="message"       />
+            <field name="status"            type="integer"      column="status"        default="false" />
+            <field name="created_at"    type="datetime"   column="created_at" />
+            <field name="updated_at"    type="datetime"   column="updated_at" />
+
+            <lifecycle-callbacks>
               <lifecycle-callback type="prePersist" method="prePersist"/>
-
               <lifecycle-callback type="preUpdate" method="preUpdate"/>
-
-          </lifecycle-callbacks>
-
-          <many-to-many field="posts" target-entity="Application\Sonata\NewsBundle\Entity\Post" mapped-by="tags" >
-          </many-to-many>
-
-      </entity>
+            </lifecycle-callbacks>
+
+            <many-to-one field="post" target-entity="Sonata\NewsBundle\Entity\Post">
+               <join-column name="post_id" referenced-column-name="id" />
+            </many-to-one>
+        </entity>
+    </doctrine-mapping>
+
+
+Post
+~~~~
+
+.. code-block:: xml
+
+    <?xml version="1.0" encoding="utf-8"?>
+    <doctrine-mapping xmlns="http://doctrine-project.org/schemas/orm/doctrine-mapping" xsi="http://www.w3.org/2001/XMLSchema-instance" schemaLocation="http://doctrine-project.org/schemas/orm/doctrine-mapping http://doctrine-project.org/schemas/orm/doctrine-mapping.xsd">
+        <entity name="Sonata\NewsBundle\Entity\Post" table="news__post">
+
+            <id name="id" type="integer" column="id">
+                <generator strategy="AUTO"/>
+            </id>
+
+            <field name="title"             type="string"       column="title"           />
+            <field name="abstract"          type="text"         column="abstract"           />
+            <field name="content"           type="text"         column="content"           />
+            <field name="enabled"           type="boolean"      column="enabled"        default="false" />
+            <field name="slug"              type="string"      column="slug" />
+            <field name="publication_date_start"   type="datetime"   column="publication_date_start"    nullable="true"/>
+            <field name="comments_enabled"    type="boolean"   column="comments_enabled" default="true"/>
+            <field name="comments_close_at"   type="datetime"  column="comments_close_at" nullable="true"/>
+            <field name="comments_default_status"   type="integer"  column="comments_default_status" nullable="false"/>
+            <field name="created_at"    type="datetime"   column="created_at" />
+            <field name="updated_at"    type="datetime"   column="updated_at" />
+
+            <lifecycle-callbacks>
+                <lifecycle-callback type="prePersist" method="prePersist"/>
+                <lifecycle-callback type="preUpdate" method="preUpdate"/>
+            </lifecycle-callbacks>
+
+            <many-to-many
+                field="tags"
+                target-entity="Sonata\NewsBundle\Entity\Tag"
+                inversed-by="posts"
+                fetch="EAGER"
+                >
+
+                <cascade>
+                   <cascade-persist />
+                </cascade>
+
+                <join-table name="news__post_tag">
+                    <join-columns>
+                        <join-column name="post_id" referenced-column-name="id"/>
+                    </join-columns>
+
+                    <inverse-join-columns>
+                        <join-column name="tag_id" referenced-column-name="id"/>
+                    </inverse-join-columns>
+                </join-table>
+            </many-to-many>
+
+            <one-to-many
+                field="comments"
+                target-entity="Sonata\NewsBundle\Entity\Comment"
+                mapped-by="post">
+
+                <cascade>
+                    <cascade-persist/>
+                </cascade>
+                <join-columns>
+                    <join-column name="id" referenced-column-name="post_id" />
+                </join-columns>
+
+                <order-by>
+                    <order-by-field name="created_at" direction="DESC" />
+                </order-by>
+
+            </one-to-many>
+        </entity>
+    </doctrine-mapping>
+
+
+Comment
+~~~~~~~
+
+.. code-block:: xml
+
+    <?xml version="1.0" encoding="utf-8"?>
+    <doctrine-mapping xmlns="http://doctrine-project.org/schemas/orm/doctrine-mapping" xsi="http://www.w3.org/2001/XMLSchema-instance" schemaLocation="http://doctrine-project.org/schemas/orm/doctrine-mapping http://doctrine-project.org/schemas/orm/doctrine-mapping.xsd">
+
+        <entity name="Sonata\NewsBundle\Entity\Tag" table="news__tag">
+
+            <id name="id" type="integer" column="id">
+                <generator strategy="AUTO"/>
+            </id>
+
+            <field name="name"          type="string"       column="title"           />
+            <field name="enabled"       type="boolean"      column="enabled"        default="false" />
+            <field name="slug"          type="string"      column="slug"    />
+            <field name="created_at"    type="datetime"   column="created_at" />
+            <field name="updated_at"    type="datetime"   column="updated_at" />
+
+            <lifecycle-callbacks>
+                <lifecycle-callback type="prePersist" method="prePersist"/>
+                <lifecycle-callback type="preUpdate" method="preUpdate"/>
+            </lifecycle-callbacks>
+
+            <many-to-many field="posts" target-entity="Sonata\NewsBundle\Entity\Post" mapped-by="tags" >
+            </many-to-many>
+
+        </entity>
       
-  </doctrine-mapping>
+    </doctrine-mapping>
 
 
 Generate getter and setter

+ 1 - 1
Resources/doc/tutorial/creating_your_first_admin_class/defining_routing.rst

@@ -10,4 +10,4 @@ Each entity required 6 routes :
 - edit
 - delete
 
-The route information are automatically generated for you. 
+The route information are automatically generated for you. So you can jump to the next chapitre.