1
0
mirror of synced 2025-01-18 06:21:40 +03:00

Add code-configuration directive, thank you Fabien!

This commit is contained in:
Benjamin Eberlei 2010-12-16 21:59:27 +01:00
parent 65fe9b86c5
commit 6a0f3f2d7b
7 changed files with 458 additions and 96 deletions

View File

@ -0,0 +1,93 @@
#Copyright (c) 2010 Fabien Potencier
#
#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.
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)

Binary file not shown.

View File

@ -0,0 +1,93 @@
ul.simple
{
padding: 5px 0 0 0;
}
ul.simple li
{
margin: 0;
margin-right: 5px;
display: inline;
}
div.configuration-block em
{
margin-bottom: 10px;
}
div.configuration-block li
{
padding: 5px;
}
div.configuration-block em
{
font-style: normal;
font-size: 90%;
}
div.jsactive
{
position: relative;
}
div.jsactive ul
{
list-style: none;
}
div.jsactive li
{
float: left;
list-style: none;
margin-left: 0;
-moz-border-radius: 5px; -webkit-border-radius: 5px; border-radius: 5px;
background-color: #ddd;
margin-right: 5px;
}
div.jsactive .selected
{
background-color: #000;
}
div.jsactive .selected a
{
color: #fff;
text-decoration: none;
}
div.jsactive .selected a:hover
{
color: #fff;
text-decoration: underline;
}
div.jsactive a
{
color: #000;
text-decoration: none;
}
div.jsactive a:hover
{
color: #000;
text-decoration: underline;
}
div.jsactive div
{
position: absolute;
top: 30px;
left: 0;
}
div.jsactive div div
{
position: static;
}
div.jsactive pre
{
margin: 0;
}

View File

@ -0,0 +1,34 @@
$(document).ready(function(){
$('div.configuration-block [class^=highlight-]').hide();
$('div.configuration-block [class^=highlight-]').width($('div.configuration-block').width());
$('div.configuration-block').addClass('jsactive');
$('div.configuration-block').addClass('clearfix');
$('div.configuration-block').each(function (){
var el = $('[class^=highlight-]:first', $(this));
el.show();
el.parents('ul').height(el.height() + 40);
});
// Global
$('div.configuration-block li').each(function(){
var str = $(':first', $(this)).html();
$(':first ', $(this)).html('');
$(':first ', $(this)).append('<a href="#">' + str + '</a>')
$(':first', $(this)).bind('click', function(){
$('[class^=highlight-]', $(this).parents('ul')).hide();
$('li', $(this).parents('ul')).removeClass('selected');
$(this).parent().addClass('selected');
var block = $('[class^=highlight-]', $(this).parent('li'));
block.show();
block.parents('ul').height(block.height() + 40);
return false;
});
});
$('div.configuration-block').each(function (){
$('li:first', $(this)).addClass('selected');
});
});

View File

@ -104,6 +104,7 @@
<title>{{ title|striptags }}{{ titlesuffix }}</title>
<link rel="stylesheet" href="{{ pathto('_static/' + style, 1) }}" type="text/css" />
<link rel="stylesheet" href="{{ pathto('_static/pygments.css', 1) }}" type="text/css" />
<link rel="stylesheet" href="{{ pathto('_static/configurationblock.css', 1) }}" type="text/css" />
{%- if not embedded %}
<script type="text/javascript">
var DOCUMENTATION_OPTIONS = {
@ -116,6 +117,7 @@
</script>
{%- for scriptfile in script_files %}
<script type="text/javascript" src="{{ pathto(scriptfile, 1) }}"></script>
<script type="text/javascript" src="{{ pathto('_static/configurationblock.js', 1) }}"></script>
{%- endfor %}
{%- if use_opensearch %}
<link rel="search" type="application/opensearchdescription+xml"

View File

@ -16,13 +16,13 @@ import sys, os
# 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.append(os.path.abspath('.'))
sys.path.append(os.path.abspath('_exts'))
# -- General configuration -----------------------------------------------------
# Add any Sphinx extension module names here, as strings. They can be extensions
# coming with Sphinx (named 'sphinx.ext.*') or your custom ones.
extensions = []
extensions = ['configurationblock']
# Add any paths that contain templates here, relative to this directory.
templates_path = ['_templates']

View File

@ -1,5 +1,5 @@
Getting Started (XML Edition)
=============================
Getting Started
===============
Doctrine 2 is a project that aims to handle the persistence of the
domain model in a non-interfering way. The Data Mapper pattern is
@ -22,9 +22,8 @@ or contain final methods. Additionally it must not implement
**clone** nor **wakeup** or :doc:`do so safely <../cookbook/implementing-wakeup-or-clone>`.
An entity contains persistable properties. A persistable property
is an instance variable of the entity that contains the data which
is persisted and retrieved by Doctrine's data mapping
capabilities.
is an instance variable of the entity that is saved into and retrieved from the database
by Doctrine's data mapping capabilities.
An Example Model: Bug Tracker
-----------------------------
@ -225,8 +224,8 @@ the bi-directional reference:
<?php
class Bug
{
protected $engineer;
protected $reporter;
private $engineer;
private $reporter;
public function setEngineer($engineer)
{
@ -252,6 +251,9 @@ the bi-directional reference:
}
class User
{
private $reportedBugs = null;
private $assignedBugs = null;
public function addReportedBug($bug)
{
$this->reportedBugs[] = $bug;
@ -298,7 +300,7 @@ the database that points from from Bugs to Products.
<?php
class Bug
{
protected $products = null; // Set protected for encapsulation
private $products = null;
public function assignToProduct($product)
{
@ -344,37 +346,64 @@ should be applied to them.
Metadata for entities are loaded using a
``Doctrine\ORM\Mapping\Driver\Driver`` implementation and Doctrine
2 already comes with XML, YAML and Annotations Drivers. In this
Getting Started Guide I will use the XML Mapping Driver. I think
XML beats YAML because of schema validation, and my favorite IDE
netbeans offers me auto-completion for the XML mapping files which
is awesome to work with and you don't have to look up all the
different metadata mapping commands all the time.
2 already comes with XML, YAML and Annotations Drivers. This
Getting Started Guide will show the mappings for all Mapping Drivers.
References in the text will be made to the XML mapping.
Since we haven't namespaced our three entities, we have to
implement three mapping files called Bug.dcm.xml, Product.dcm.xml
and User.dcm.xml and put them into a distinct folder for mapping
configurations.
and User.dcm.xml (or .yml) and put them into a distinct folder for mapping
configurations. For the annotations driver we need to use
doc-block comments on the entity classes themselves.
The first discussed definition will be for the Product, since it is
the most simple one:
.. code-block:: xml
.. configuration-block::
<doctrine-mapping xmlns="http://doctrine-project.org/schemas/orm/doctrine-mapping"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://doctrine-project.org/schemas/orm/doctrine-mapping
http://doctrine-project.org/schemas/orm/doctrine-mapping.xsd">
<entity name="Product" table="zf_products">
<id name="id" type="integer" column="product_id">
<generator strategy="AUTO" />
</id>
<field name="name" column="product_name" type="string" />
</entity>
</doctrine-mapping>
.. code-block:: php
<?php
/**
* @Entity @Table(name="products")
*/
class Product
{
/** @Id @Column(type="integer") @GeneratedValue */
public $id;
/** @Column(type="string") */
public $name;
}
.. code-block:: xml
<doctrine-mapping xmlns="http://doctrine-project.org/schemas/orm/doctrine-mapping"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://doctrine-project.org/schemas/orm/doctrine-mapping
http://doctrine-project.org/schemas/orm/doctrine-mapping.xsd">
<entity name="Product" table="products">
<id name="id" type="integer" column="product_id">
<generator strategy="AUTO" />
</id>
<field name="name" column="product_name" type="string" />
</entity>
</doctrine-mapping>
.. code-block:: yaml
Product:
type: entity
table: products
id:
id:
type: integer
generator:
strategy: AUTO
fields:
name:
type: string
The top-level ``entity`` definition tag specifies information about
the class and table-name. The primitive type ``Product::$name`` is
@ -387,43 +416,99 @@ case of PostgreSql and Oracle.
We then go on specifying the definition of a Bug:
.. code-block:: xml
.. configuration-block::
.. code-block:: php
<doctrine-mapping xmlns="http://doctrine-project.org/schemas/orm/doctrine-mapping"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://doctrine-project.org/schemas/orm/doctrine-mapping
http://doctrine-project.org/schemas/orm/doctrine-mapping.xsd">
<entity name="Bug" table="zf_bugs">
<id name="id" type="integer" column="bug_id">
<generator strategy="AUTO" />
</id>
<field name="description" column="bug_description" type="text" />
<field name="created" column="bug_created" type="datetime" />
<field name="status" column="bug_status" type="string" />
<many-to-one target-entity="User" field="reporter" inversed-by="reportedBugs">
<join-column name="reporter_id" referenced-column-name="account_id" />
</many-to-one>
<many-to-one target-entity="User" field="engineer" inversed-by="assignedBugs">
<join-column name="engineer_id" referenced-column-name="account_id" />
</many-to-one>
<many-to-many target-entity="Product" field="products">
<join-table name="zf_bugs_products">
<join-columns>
<join-column name="bug_id" referenced-column-name="bug_id" />
</join-columns>
<inverse-join-columns>
<join-column name="product_id" referenced-column-name="product_id" />
</inverse-join-columns>
</join-table>
</many-to-many>
</entity>
</doctrine-mapping>
<?php
/**
* @Entity @Table(name="bugs")
*/
class Bug
{
/**
* @Id @Column(type="integer") @GeneratedValue
*/
public $id;
/**
* @Column(type="string")
*/
public $description;
/**
* @Column(type="datetime")
*/
public $created;
/**
* @Column(type="string")
*/
public $status;
/**
* @ManyToOne(targetEntity="User", inversedBy="assignedBugs")
*/
private $engineer;
/**
* @ManyToOne(targetEntity="User", inversedBy="reportedBugs")
*/
private $reporter;
/**
* @ManyToMany(targetEntity="Product")
*/
private $products = null; // Set private for encapsulation
}
.. code-block:: xml
<doctrine-mapping xmlns="http://doctrine-project.org/schemas/orm/doctrine-mapping"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://doctrine-project.org/schemas/orm/doctrine-mapping
http://doctrine-project.org/schemas/orm/doctrine-mapping.xsd">
<entity name="Bug" table="bugs">
<id name="id" type="integer">
<generator strategy="AUTO" />
</id>
<field name="description" type="text" />
<field name="created" type="datetime" />
<field name="status" type="string" />
<many-to-one target-entity="User" field="reporter" inversed-by="reportedBugs" />
<many-to-one target-entity="User" field="engineer" inversed-by="assignedBugs" />
<many-to-many target-entity="Product" field="products" />
</entity>
</doctrine-mapping>
.. code-block:: yaml
Bug:
type: entity
table: bugs
id:
id:
type: integer
generator:
strategy: AUTO
fields:
description:
type: text
created:
type: datetime
status:
type: string
manyToOne:
reporter:
targetEntity: User
inversedBy: reportedBugs
engineer:
targetEntity: User
inversedBy: assignedBugs
manyToMany:
products:
targetEntity: Product
Here again we have the entity, id and primitive type definitions.
The column names are used from the Zend\_Db\_Table examples and
@ -456,26 +541,79 @@ schema details all the time.
The last missing definition is that of the User entity:
.. code-block:: xml
.. configuration-block::
<doctrine-mapping xmlns="http://doctrine-project.org/schemas/orm/doctrine-mapping"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://doctrine-project.org/schemas/orm/doctrine-mapping
http://doctrine-project.org/schemas/orm/doctrine-mapping.xsd">
<entity name="User" table="zf_accounts">
<id name="id" type="integer" column="account_id">
<generator strategy="AUTO" />
</id>
<field name="name" column="account_name" type="string" />
<one-to-many target-entity="Bug" field="reportedBugs" mapped-by="reporter" />
<one-to-many target-entity="Bug" field="assignedBugs" mapped-by="engineer" />
</entity>
</doctrine-mapping>
.. code-block:: php
<?php
/**
* @Entity @Table(name="users")
*/
class User
{
/**
* @Id @GeneratedValue @Column(type="integer")
* @var string
*/
public $id;
/**
* @Column(type="string")
* @var string
*/
public $name;
/**
* @OneToMany(targetEntity="Bug", mappedBy="reporter")
* @var Bug[]
*/
protected $reportedBugs = null;
/**
* @OneToMany(targetEntity="Bug", mappedBy="engineer")
* @var Bug[]
*/
protected $assignedBugs = null;
.. code-block:: xml
<doctrine-mapping xmlns="http://doctrine-project.org/schemas/orm/doctrine-mapping"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://doctrine-project.org/schemas/orm/doctrine-mapping
http://doctrine-project.org/schemas/orm/doctrine-mapping.xsd">
<entity name="User" name="users">
<id name="id" type="integer">
<generator strategy="AUTO" />
</id>
<field name="name" type="string" />
<one-to-many target-entity="Bug" field="reportedBugs" mapped-by="reporter" />
<one-to-many target-entity="Bug" field="assignedBugs" mapped-by="engineer" />
</entity>
</doctrine-mapping>
.. code-block:: yaml
User:
type: entity
table: users
id:
id:
type: integer
generator:
strategy: AUTO
fields:
name:
type: string
oneToMany:
reportedBugs:
targetEntity: Bug
mappedBy: reporter
assignedBugs:
targetEntity: Bug
mappedBy: engineer
Here are some new things to mention about the ``one-to-many`` tags.
Remember that we discussed about the inverse and owning side. Now
@ -511,7 +649,9 @@ step:
$config->setAutoGenerateProxyClasses((APPLICATION_ENV == "development"));
// Mapping Configuration (4)
$driverImpl = new Doctrine\ORM\Mapping\Driver\XmlDriver(__DIR__."/config/mappings");
$driverImpl = new Doctrine\ORM\Mapping\Driver\XmlDriver(__DIR__."/config/mappings/xml");
//$driverImpl = new Doctrine\ORM\Mapping\Driver\XmlDriver(__DIR__."/config/mappings/yml");
//$driverImpl = $config->newDefaultAnnotationDriver(__DIR__."/entities");
$config->setMetadataDriverImpl($driverImpl);
// Caching Configuration (5)
@ -603,10 +743,10 @@ doctrine command. Its a fairly simple file:
You can then change into your project directory and call the
Doctrine command-line tool:
.. code-block:: bash
::
doctrine@my-desktop> cd myproject/
doctrine@my-desktop> doctrine orm:schema-tool:create
doctrine@my-desktop> doctrine orm:schema-tool:create --force
.. note::
@ -624,16 +764,16 @@ During the development you probably need to re-create the database
several times when changing the Entity metadata. You can then
either re-create the database:
.. code-block:: bash
::
doctrine@my-desktop> doctrine orm:schema-tool:drop
doctrine@my-desktop> doctrine orm:schema-tool:create
doctrine@my-desktop> doctrine orm:schema-tool:drop --force
doctrine@my-desktop> doctrine orm:schema-tool:create --force
Or use the update functionality:
.. code-block:: bash
::
doctrine@my-desktop> doctrine orm:schema-tool:update
doctrine@my-desktop> doctrine orm:schema-tool:update --force
The updating of databases uses a Diff Algorithm for a given
Database Schema, a cornerstone of the ``Doctrine\DBAL`` package,