1
1
Alternate Locale Handling
2
2
=========================
3
3
4
- The CMF provides a powerful way to persist document in different locales.
5
- Each of those translated documents are representations of another. In a
6
- SEO context it would be great to show the available routes to translations
7
- of the current representation.
4
+ .. versionadded :: 1.1
5
+ Support for handling alternate locales was added in SeoBundle version 1.1.0.
8
6
9
- Example
10
- -------
7
+ Alternate locales are a way of telling search engines how to find translations
8
+ of the current page. The SeoBundle provides a way to manage alternate locales
9
+ and render them together with the other SEO information.
11
10
12
- Lets persist a document in three locales.::
11
+ When the alternate locale handling is set up and found alternates, you will
12
+ find links like the following in the ``<head> `` part of your HTML pages:
13
13
14
- // src/Acme/ApplicationBundle/DataFixtures/Doctrine/PHPCR/ExampleFixture.php
14
+ .. code-block :: html
15
15
16
- <?php
16
+ <link rel =" alternate" href =" /fr/le-titre" hreflang =" fr" >
17
+ <link rel =" alternate" href =" /de/der-titel" hreflang =" de" >
17
18
18
- namespace AppBundle\DataFixtures\PHPCR;
19
+ When using PHPCR-ODM, there is almost no work to do, as the bundle can use the
20
+ Doctrine meta data to figure out which translations exists for a content. More
21
+ information on translating content with the PHPCR-ODM is in the chapter
22
+ :doc: `Doctrine PHPCR-ODM Multilanguage Support <../phpcr_odm/multilang >`.
19
23
20
- use Doctrine\Common\DataFixtures\FixtureInterface;
21
- use Doctrine\Common\Persistence\ObjectManager;
22
- use Doctrine\ODM\PHPCR\DocumentManager;
23
- use Symfony\Cmf\Bundle\ContentBundle\Doctrine\Phpcr\StaticContent;
24
- use Symfony\Cmf\Bundle\RoutingBundle\Doctrine\Phpcr\Route;
24
+ Setting Up Alternate Locale Support
25
+ -----------------------------------
25
26
26
- /**
27
- * @author Maximilian Berghoff <[email protected] >
28
- */
29
- class ExampleFeature implements FixtureInterface
30
- {
31
- /**
32
- * Load data fixtures with the passed EntityManager
33
- *
34
- * @param DocumentManager|ObjectManager $manager
35
- */
36
- public function load(ObjectManager $manager)
37
- {
38
- $parent = $manager->find(null, '/cms/routes');
39
-
40
- $document = new StaticContent();
41
- $document->setTitle('The Title');
42
- $document->setBody('The body is the main content');
43
- $manager->persist($document);
44
- $manager->bindTranslation($document, 'en');
45
- $route = new Route();
46
- $route->setPosition($parent, 'en');
47
- $route->setCondition($document);
48
- $manager->persist($route);
49
-
50
- $document->setTitle('Der Titel');
51
- $document->setBody('Der Body ist der Content');
52
- $manager->bindTranslation($document, 'en');
53
- $route = new Route();
54
- $route->setPosition($parent, 'de');
55
- $route->setCondition($document);
56
- $manager->persist($route);
57
-
58
- $document->setTitle('Le titre');
59
- $document->setBody('Le contenu principale');
60
- $manager->bindTranslation($document, 'fr');
61
- $route = new Route();
62
- $route->setPosition($parent, 'fr');
63
- $route->setCondition($document);
64
- $manager->persist($route);
65
-
66
- $manager->flush();
67
- }
68
- }
69
-
70
- This creates a content document for the languages german, english and french and its routes.
71
- So the routes are persisted as objects, but the content is available under the following urls:
72
-
73
- +--------------------+---------------------+
74
- | locale | url |
75
- +================================+=========+
76
- | ``english `` | ``/en/the-title `` |
77
- +--------------------+---------------------+
78
- | ``german `` | ``/de/der-title `` |
79
- +--------------------+---------------------+
80
- | ``french `` | ``/fr/le-titre `` |
81
- +--------------------+---------------------+
82
-
83
- - english: /en/
84
- - german: /de/der-titel
85
-
86
- .. note ::
87
- To get more information about translating content by the PHPCR-ODM have a look
88
- at :doc: `Doctrine PHPCR-ODM Multilanguage Support<../phpcr_odm/multilang> `.
89
-
90
- When viewing the page in one language, we would expect hints how to navigate to the others.
91
- Search engines expect the following in the ``<head> `` section of the page:
92
-
93
- <link rel="alternate" href="/fr/le-titre" hreflang="fr" />
94
- <link rel="alternate" href="/de/der-titel" hreflang="de" />
95
-
96
- Configuration
97
- -------------
98
-
99
- The SeoBundle serves a ``AlternateLocaleProvider `` to build alternate locale information
100
- for a given content based on the PHPCR-ODM. You can easily enable that by:
27
+ Enable alternate locale support:
101
28
102
29
.. configuration-block ::
103
30
@@ -106,151 +33,47 @@ for a given content based on the PHPCR-ODM. You can easily enable that by:
106
33
# app/config/config.yml
107
34
cmf_seo :
108
35
alternate_locale : ~
109
- persistence :
110
- phpcr : ~
111
36
112
37
.. code-block :: xml
113
38
114
39
<!-- app/config/config.xml -->
115
40
<?xml version =" 1.0" encoding =" UTF-8" ?>
116
41
<container xmlns =" http://symfony.com/schema/dic/services" >
117
42
<config xmlns =" http://cmf.symfony.com/schema/dic/seo" >
118
- <alternate-locale enabled =" true" />
119
- <persistence >
120
- <phpcr
121
- enabled =" true"
122
- />
123
- </persistence >
43
+ <alternate-locale />
124
44
</config >
125
45
</container >
126
46
127
47
.. code-block :: php
128
48
129
49
$container->loadFromExtension('cmf_seo', array(
130
- 'alternate_locale' => array (
131
- 'enabled' => true,
132
- ),
133
- 'persistence' => array(
134
- 'phpcr' => array('enabled' => true),
135
- ),
50
+ 'alternate_locale' => true,
136
51
));
137
52
138
- You have to enable persistence by PHPCR to have the default provider available.
139
-
140
- Create your own provider
141
- ------------------------
142
-
143
- The default provider serves the routes for the alternate locale contents directly from the
144
- PHPCR-ODM. For other persistence layers or custom needs on the translated location URLs you can
145
- create your own provider by implementing the ``AlternateLocaleProviderInterface ``::
146
-
147
- // src/Acme/ApplicationBundle/AlternateLocaleProvider.php
148
-
149
- use Symfony\Cmf\Bundle\SeoBundle\AlternateLocaleProviderInterface;
150
- use Symfony\Cmf\Bundle\SeoBundle\Model\AlternateLocale;
151
- use Symfony\Cmf\Bundle\SeoBundle\Model\AlternateLocaleCollection;
152
-
153
- class AlternateLocaleProvider implements AlternateLocaleProviderInterface
154
- {
155
- /**
156
- * Creates a collection of AlternateLocales for one content object.
157
- *
158
- * @param object $content
159
- *
160
- * @return AlternateLocaleCollection
161
- */
162
- public function createForContent($content)
163
- {
164
- $alternateLocaleCollection = new AlternateLocaleCollection();
165
- // get the alternate locales for the given content
166
- $alternateLocales = $this->getAllForContent($content);
167
-
168
- // add the alternate locales except the current one
169
- $currentLocale = $content->getLocale();
170
- foreach ($alternateLocales as $locale) {
171
- if ($locale === $currentLocale) {
172
- continue;
173
- }
53
+ If you are using PHPCR-ODM, enabling ``phpcr: ~ `` in the seo bundle
54
+ configuration will activate a listener that extracts the alternate locales
55
+ from the PHPCR-ODM meta data. For other storage systems, you will need to
56
+ write a provider and configure the bundle to use that provider - see below.
174
57
175
- $alternateLocaleCollection->add(
176
- new AlternateLocale(
177
- $this->urlGenerator->generate($content, array('_locale' => $locale), true),
178
- $locale
179
- )
180
- );
181
- }
58
+ Rendering Alternate Locales
59
+ ---------------------------
182
60
183
- return $alternateLocaleCollection;
184
- }
61
+ The alternate locales are rendered together with the other SEO metadata by the
62
+ twig function `` sonata_seo_metadatas ``.
185
63
186
- /**
187
- * Creates a collection of AlternateLocales for many content object.
188
- *
189
- * @param array|object[] $contents
190
- *
191
- * @return AlternateLocaleCollection[]
192
- */
193
- public function createForContents(array $contents)
194
- {
195
- $result = array();
196
- foreach ($contents as $content) {
197
- $result[] = $this->createForContent($content);
198
- }
64
+ Creating a Custom Alternate Locales Provider
65
+ --------------------------------------------
199
66
200
- return $result;
201
- }
202
-
203
- /**
204
- * Creates a list of locales the content is also persisd
205
- *
206
- * @var object $content
207
- * @return array The list of locales
208
- */
209
- public function getAllForContent($content)
210
- {
211
- $list = array();
212
- // implement you logic
213
-
214
- return $list;
215
- }
216
-
217
- }
218
-
219
- Create a service for your provider:
220
-
221
- .. configuration-block ::
222
-
223
- .. code-block :: yaml
224
-
225
- services :
226
- acme.application.alternate_locale.provider
227
- class : " Acme\A pplicationBundle\A lternateLocaleProvider"
228
-
229
- .. code-block :: xml
230
-
231
- <?xml version =" 1.0" ?>
232
-
233
- <container xmlns =" http://symfony.com/schema/dic/services"
234
- xmlns : xsi =" http://www.w3.org/2001/XMLSchema-instance"
235
- xsi : schemaLocation =" http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd" >
236
-
237
- <services >
238
- <service id =" acme.application.alternate_locale.provider" class =" Acme\ApplicationBundle\AlternateLocaleProvider" >
239
- </service >
240
- </services >
241
-
242
- </container >
243
-
244
- .. code-block :: php
245
-
246
- use Symfony\Component\DependencyInjection\Definition;
247
-
248
- $container->setDefinition('acme.application.alternate_locale.provider', new Definition(
249
- 'Acme\ApplicationBundle\AlternateLocaleProvider'
250
- ));
67
+ The alternate locale provider is asked to provide translated URLs for a content
68
+ object. The bundle comes with a provider for PHPCR-ODM. For other persistence
69
+ layers or custom requirements on the translated URLs you need to create your
70
+ own provider implementing the ``AlternateLocaleProviderInterface ``. For some
71
+ inspiration, have a look at
72
+ ``Symfony\Cmf\Bundle\SeoBundle\Doctrine\Phpcr\AlternateLocaleProvider ``.
251
73
252
- Now you have to configure ``CmfSeoBundle `` to use your custom alternate locale provider instead of the default one.
253
- Set the ``alternate_locale.provider_id `` to the service you just created:
74
+ Define a service for your provider, so that you can configure the seo bundle to
75
+ use your custom alternate locale provider instead of the default one. Set the
76
+ ``alternate_locale.provider_id `` to the service you just created:
254
77
255
78
.. configuration-block ::
256
79
@@ -259,25 +82,26 @@ Set the ``alternate_locale.provider_id`` to the service you just created:
259
82
# app/config/config.yml
260
83
cmf_seo :
261
84
alternate_locale :
262
- provider_id : acme.application. alternate_locale.provider
85
+ provider_id : alternate_locale.provider
263
86
264
87
.. code-block :: xml
265
88
266
89
<!-- app/config/config.xml -->
267
90
<?xml version =" 1.0" encoding =" UTF-8" ?>
268
91
<container xmlns =" http://symfony.com/schema/dic/services" >
269
92
<config xmlns =" http://cmf.symfony.com/schema/dic/seo" >
270
- <alternate-locale provider-id =" acme.application. alternate_locale.provider" />
93
+ <alternate-locale provider-id =" alternate_locale.provider" />
271
94
</config >
272
95
</container >
273
96
274
97
.. code-block :: php
275
98
276
99
$container->loadFromExtension('cmf_seo', array(
277
100
'alternate_locale' => array (
278
- 'provider_id' => acme.application. alternate_locale.provider,
101
+ 'provider_id' => ' alternate_locale.provider' ,
279
102
),
280
103
));
281
104
282
105
.. versionadded :: 1.2
283
- For activated :doc: `Sitemap<sitemap> ` the alternate locales will be pushed into the sitemap too.
106
+ When :doc: `Sitemaps <sitemap >` are enabled, alternate locales are also
107
+ added to the Sitemap.
0 commit comments