Skip to content
This repository was archived by the owner on Sep 16, 2021. It is now read-only.

Commit 2e0c0cd

Browse files
committed
Final fixes and additions
1 parent 3b16b81 commit 2e0c0cd

File tree

9 files changed

+279
-81
lines changed

9 files changed

+279
-81
lines changed

bundles/index.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,8 @@ Bundles
1515
routing_auto/index
1616
routing/index
1717
search/index
18+
seo/index
1819
simple_cms/index
1920
tree_browser/index
20-
seo/index
2121

2222
.. include:: map.rst.inc

bundles/map.rst.inc

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,12 @@ library or they introduce a complete new concept.
5959

6060
* :doc:`search/introduction`
6161

62+
* :doc:`seo/index`
63+
64+
* :doc:`seo/introduction`
65+
* :doc:`seo/seo_aware`
66+
* :doc:`seo/extractors`
67+
6268
* :doc:`tree_browser/index`
6369

6470
* :doc:`tree_browser/introduction`

bundles/seo/extractors.rst

Lines changed: 39 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -2,34 +2,38 @@ Using Extractors to Retrieve the Seo Metadata
22
=============================================
33

44
Instead of setting every value to the ``SeoMetadata`` manually, an extractor
5-
can do the work for you. Extractors are executed when an object implements a
6-
specific interface. The method required by that interface will return the
7-
value for the specific SEO data. The extractor will then update the
5+
can do the work for you. Extractors are executed when the content object
6+
implements a specific interface. The method required by that interface will
7+
return the value for the specific SEO data. The extractor will then update the
88
``SeoMetadata`` object for the current object with the returned value.
99

1010
Available Extractors
1111
--------------------
1212

13-
+-----------------------------------+---------------------------+----------------------------------------------+
14-
| ExtractorInterface | Method | Type |
15-
+===================================+===========================+==============================================+
16-
| ``SeoDescriptionReadInterface`` | ``getSeoDescription()`` | Returns the meta description |
17-
+-----------------------------------+---------------------------+----------------------------------------------+
18-
| ``SeoTitleReadInterface`` | ``getSeoTitle()`` | Returns the page title |
19-
+-----------------------------------+---------------------------+----------------------------------------------+
20-
| - | ``getTitle()`` | If the document has a ``getTitle()`` method, |
21-
| | | it'll be used as the page title |
22-
+-----------------------------------+---------------------------+----------------------------------------------+
23-
| ``SeoOriginalUrlReadInterface`` | ``getSeoOriginalUrl()`` | Returns a absolute url object to redirect to |
24-
| | | or create a canonical link from |
25-
+-----------------------------------+---------------------------+----------------------------------------------+
26-
| ``SeoOriginalRouteReadInterface`` | ``getSeoOriginalRoute()`` | Return a ``Route`` object to redirect to |
27-
| | | or create a canonical link from |
28-
+-----------------------------------+---------------------------+----------------------------------------------+
13+
+--------------------------------+---------------------------+----------------------------------------------+
14+
| ExtractorInterface | Method | Type |
15+
+================================+===========================+==============================================+
16+
| ``DescriptionReadInterface`` | ``getSeoDescription()`` | Returns the meta description |
17+
+--------------------------------+---------------------------+----------------------------------------------+
18+
| ``TitleReadInterface`` | ``getSeoTitle()`` | Returns the page title |
19+
+--------------------------------+---------------------------+----------------------------------------------+
20+
| - | ``getTitle()`` | If the document has a ``getTitle()`` method, |
21+
| | | it'll be used as the page title |
22+
+--------------------------------+---------------------------+----------------------------------------------+
23+
| ``OriginalUrlReadInterface`` | ``getSeoOriginalUrl()`` | Returns a absolute url object to redirect to |
24+
| | | or create a canonical link from |
25+
+--------------------------------+---------------------------+----------------------------------------------+
26+
| ``OriginalRouteReadInterface`` | ``getSeoOriginalRoute()`` | Return a ``Route`` object to redirect to |
27+
| | | or create a canonical link from |
28+
+--------------------------------+---------------------------+----------------------------------------------+
29+
| ``ExtrasReadInterface`` | ``getSeoExtras()`` | Returns an associative array using |
30+
| | | ``property``, ``http-equiv`` and ``name`` |
31+
| | | as keys (see below from an example). |
32+
+--------------------------------+---------------------------+----------------------------------------------+
2933

3034
.. note::
3135

32-
The interfaces live in the ``Symfony\Cmf\Bundle\SeoBundle\Extractor``
36+
The interfaces life in the ``Symfony\Cmf\Bundle\SeoBundle\Extractor``
3337
namespace.
3438

3539
An Example
@@ -42,10 +46,11 @@ description, you can implement both interfaces and your result will be::
4246
// src/Acme/BlogBundle/Document/Article.php
4347
namespace Acme\BlogBundle\Document;
4448

45-
use Symfony\Cmf\Bundle\SeoBundle\Extractor\SeoTitleReadInterface;
46-
use Symfony\Cmf\Bundle\SeoBundle\Extractor\SeoDescriptionReadInterface;
49+
use Symfony\Cmf\Bundle\SeoBundle\Extractor\TitleReadInterface;
50+
use Symfony\Cmf\Bundle\SeoBundle\Extractor\DescriptionReadInterface;
51+
use Symfony\Cmf\Bundle\SeoBundle\Extractor\ExtrasReadInterface;
4752

48-
class Article implements SeoTitleReadInterface, SeoDescriptionReadInterface
53+
class Article implements TitleReadInterface, DescriptionReadInterface, ExtraReadInterface
4954
{
5055
protected $title;
5156
protected $publishDate;
@@ -59,7 +64,17 @@ description, you can implement both interfaces and your result will be::
5964

6065
public function getSeoDescription()
6166
{
62-
return $this->title;
67+
return $this->intro;
68+
}
69+
70+
public function getSeoExtras()
71+
{
72+
return array(
73+
'property' => array(
74+
'og:title' => $this->title,
75+
'og:description' => $this->description,
76+
),
77+
);
6378
}
6479
}
6580

bundles/seo/introduction.rst

Lines changed: 18 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,14 @@ document. This metadata can hold:
102102
* The meta keywords;
103103
* The meta description;
104104
* The original URL (when more than one URL contains the same content).
105-
105+
* Anything else that uses the ``<meta>`` tag with the ``property``, ``name``
106+
or ``http-equiv`` type (e.g. Open Graph data).
107+
108+
The content object is retrieved from the request attributes. By default, it
109+
uses the ``DynamicRouter::CONTENT_KEY`` constant when the
110+
:doc:`RoutingBundle <../routing/introduction>` is installed. To change this,
111+
or if you don't use the RoutingBundle, you can configure it with
112+
``cmf_seo.content_key``.
106113
This bundle provides two ways of using this metadata:
107114

108115
#. Implementing the ``SeoAwareInterface`` and persisting the ``SeoMetadata``
@@ -165,25 +172,28 @@ you want to change that to redirect instead, you can set the
165172
),
166173
);
167174
175+
.. _bundles-seo-title-description-emplate:
176+
168177
Defining a Title and Description Template
169178
-----------------------------------------
170179

171180
Most of the times, the title of a site has a static and a dynamic part. For
172181
instance, "The title of the Page - Symfony". Here, "- Symfony" is static and
173-
"The title of the Page" will be replaced by the current title. It is of course
174-
not nice if you had to add this static part to all your titles in documents.
182+
"The title of the Page" will be replaced by the current title. It would not be
183+
nice if you had to add this static part to all your titles in documents.
175184

176-
That's why the CmfSeoBundle provides defining a title and description
177-
template. When using these settings, there are 2 placeholders available:
185+
The CmfSeoBundle allows you to define a title and description template for
186+
this reason. When using these settings, there are 2 placeholders available:
178187
``%content_title%`` and ``%content_description%``. These will be replaced with
179188
the title extracted from the content object and the description extracted from
180189
the content object.
181190

182191
.. caution::
183192

184-
The default title and description set by the SonataSeoBundle do override
185-
this template. You should make sure that the defaults also follow the
186-
template.
193+
The title and description template is only used when the title is not set
194+
on the content object or when the content object is not available,
195+
otherwise it'll use the default set by the SonataSeoBundle. You should
196+
make sure that the defaults also follow the template.
187197

188198
For instance, to configure the titles of the symfony.com pages, you would do:
189199

bundles/seo/seo_aware.rst

Lines changed: 66 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ the ``SeoMetadata``::
1212
// src/Acme/SiteBundle/Document/Page.php
1313
namespace Acme\SiteBundle\Document;
1414

15-
use Symfony\Cmf\Bundle\SeoBundle\Model\SeoAwareInterface;
15+
use Symfony\Cmf\Bundle\SeoBundle\SeoAwareInterface;
1616

1717
class Page implements SeoAwareInterface
1818
{
@@ -32,6 +32,9 @@ the ``SeoMetadata``::
3232

3333
Now you can set some SEO data for this ``Page`` using the metadata::
3434

35+
use Acme\SiteBundle\Document\Page;
36+
use Symfony\Cmf\Bundle\SeoBundle\SeoMetadata;
37+
3538
$page = new Page();
3639
// ... set some page properties
3740

@@ -41,32 +44,6 @@ Now you can set some SEO data for this ``Page`` using the metadata::
4144

4245
$page->setSeoMetadata($pageMetadata);
4346

44-
// src/Acme/SiteBundle/DataFixture/PHPCR/LoadPageData.php
45-
namespace Acme\SiteBundle\DataFixtures\PHPCR;
46-
47-
use Acme\SiteBundle\Document\Page;
48-
use Symfony\Cmf\Bundle\SeoBundle\Model\SeoMetadata;
49-
use Doctrine\Common\Persistence\ObjectManager;
50-
use Doctrine\Common\DataFixtures\FixtureInterface;
51-
52-
class LoadPageData implements FixtureInterface
53-
{
54-
public function load(ObjectManager $manager)
55-
{
56-
$page = new Page();
57-
// ... set some page properties
58-
59-
$pageMetadata = new SeoMetadata();
60-
$pageMetadata->setDescription('A special SEO description.');
61-
$pageMetadata->setTags('seo, cmf, symfony');
62-
63-
$page->setSeoMetadata($pageMetadata);
64-
65-
$manager->persist($page);
66-
$manager->flush();
67-
}
68-
}
69-
7047
Doctrine PHPCR-ODM Integration
7148
------------------------------
7249

@@ -118,7 +95,7 @@ After you've enabled PHPCR, map your seoMetadata as a child:
11895
// src/Acme/SiteBundle/Document/Page.php
11996
namespace Acme\SiteBundle\Document;
12097
121-
use Symfony\Cmf\Bundle\SeoBundle\Model\SeoAwareInterface;
98+
use Symfony\Cmf\Bundle\SeoBundle\SeoAwareInterface;
12299
use Doctrine\ODM\PHPCR\Mapping\Annotations as PHPCR;
123100
124101
/**
@@ -192,20 +169,73 @@ Doctrine ORM
192169
------------
193170

194171
You can also use the Doctrine ORM with the CmfSeoBundle. You can just use the
195-
``Symfony\Cmf\Bundle\SeoBundle\Model\SeoMetadata`` class and map it as an
196-
object.
172+
``Symfony\Cmf\Bundle\SeoBundle\SeoMetadata`` class and map it as an
173+
object:
197174

198-
You can also choose put the ``SeoMetadata`` class into a seperate table and
199-
adding a relation between the ``SeoMetadata`` class and the content entity. To
175+
.. configuration-block::
176+
177+
.. code-block:: php-annotations
178+
179+
// src/Acme/SiteBundle/Entity/Page.php
180+
namespace Acme\SiteBundle\Entity;
181+
182+
use Symfony\Cmf\Bundle\SeoBundle\SeoAwareInterface;
183+
use Doctrine\ORM\Mapping as ORM;
184+
185+
/**
186+
* @ORM\Entity()
187+
*/
188+
class Page implements SeoAwareInterface
189+
{
190+
/**
191+
* @ORM\Column(type="object")
192+
*/
193+
protected $seoMetadata;
194+
195+
// ...
196+
}
197+
198+
.. code-block:: yaml
199+
200+
# src/Acme/SiteBundle/Resources/config/doctrine/Page.orm.yml
201+
Acme\SiteBundle\Entity\Page:
202+
# ...
203+
fields:
204+
# ...
205+
seoMetadata:
206+
type: object
207+
208+
.. code-block:: xml
209+
210+
<!-- src/Acme/SiteBundle/Resources/config/doctrine/Page.orm.xml -->
211+
<?xml version="1.0" encoding="UTF-8" ?>
212+
<doctrine-mapping xmlns="http://doctrine-project.org/schemas/orm/doctrine-mapping"
213+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
214+
xsi:schemaLocation="http://doctrine-project.org/schemas/orm/doctrine-mapping
215+
http://doctrine-project.org/schemas/orm/doctrine-mapping.xsd">
216+
217+
<entity name="Acme\SiteBundle\Entity\Page">
218+
<!-- ... -->
219+
<field name="seoMetadata" type="object" />
220+
</entity>
221+
</doctrine-mapping>
222+
223+
You can also choose to put the ``SeoMetadata`` class into a seperate table. To
200224
do this, you have to enable ORM support just like you enabled PHPCR enabled
201-
above.
225+
above and add a OneToOne or ManyToOne relation between the content entity and
226+
the ``SeoMetadata`` entity.
202227

203228
Form Type
204229
---------
205230

206231
The bundle also provides a special form type called ``seo_metadata``. This
207232
form type can be used in forms to edit the ``SeoMetadata`` object.
208233

234+
.. caution::
235+
236+
The bundles requires the `BurgovKeyValueFormBundle`_ when using the form
237+
type. Make sure you install and enable it.
238+
209239
Sonata Admin Integration
210240
------------------------
211241

@@ -214,9 +244,9 @@ Extension. This extension adds a field for the ``SeoMetadata`` when an admin
214244
edits an objec that implements the ``SeoAwareInterface`` in the Sonata Admin
215245
panel.
216246

217-
.. note::
247+
.. caution::
218248

219-
The bundles requires the `BurgovKeyValueFormBundle`_ when using the sonata
220-
admin. Make sure you install and enable it.
249+
The Sonata Admin uses the Form Type provided by the CmfSeoBundle, make
250+
sure you have the `BurgovKeyValueFormBundle`_ installed.
221251

222252
.. _`BurgovKeyValueFormBundle`: https://github.com/Burgov/KeyValueFormBundle

reference/configuration/routing.rst

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -365,7 +365,6 @@ phpcr
365365
),
366366
));
367367
368-
369368
enabled
370369
*******
371370

0 commit comments

Comments
 (0)