Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: [symfony] system artykułów - różne języki
Forum PHP.pl > Forum > PHP > Frameworki
joshuaBE
Hej,

Buduje w symfony system artykułów. Strona na której będą umieszczane będzie w różnych językach, i każdy język musi mieć kompletnie inny zbiór artykułów. Dodatkowo, tytuły ( w moim schemacie tytuł to jest headline ) mogą się w różnych językach powtarzać. Jak powinienem zbudować schemat takiej tabeli? Zrobiłem tak, jak niżej ale może w symfony są jakieś inne zalecenia?

CODE
JbArticle:
actAs:
Timestampable: ~
Sluggable:
fields: [ headline ]
uniqueBy: [ headline, lang ]
columns:
writer_id: { type: integer }
title: { type: string(150), notnull: true }
description: { type: string(500), notnull: true }
keywords: { type: string(255) }
headline: { type: string(80), notnull: true }
content: { type: string(10000), notnull: true }
redirection: { type: string(255) }
additional_scripts: { type: string(2000) }
is_main: { type: boolean, notnull: true, default: 0 }
is_disabled: { type: boolean, notnull: true, default: 0 }
is_finished: { type: boolean, notnull: true, default: 0 }
is_published: { type: boolean, notnull: true, default: 0 }
is_tested: { type: boolean, notnull: true, default: 0 }
is_hittail: { type: boolean, notnull: true, default: 0 }
is_review: { type: boolean, notnull: true, default: 0 }
lang: { type: string(2), notnull: true, fixed: true }
indexes:
name_lang:
fields: [ headline, lang ]
relations:
JbUser: { onDelete: SET NULL, local: writer_id, foreign: id, foreignAlias: JbArticles }


Pojawia się tutaj problem z routingiem, URLe mają wyglądać tak:

/pl/przewodnik/tytul

/guide/tytul

czyli dla angielskiego, język nie ma się pojawiać w urlu, ale jak wtedy pobrać artykul? To co ja mam nie może działać, bo nie ma w roucie 'guide' zmiennej 'lang'.

CODE
guide:
url: /guide/:slug
class: sfDoctrineRoute
options: { model: JbArticle, type: object }
param: { module: article, action: show }
requirements: { lang: en }

przewodnik:
url: /:lang/przewodnik/:slug
class: sfDoctrineRoute
options: { model: JbArticle, type: object }
param: { module: article, action: show }
requirements: { lang: pl }



Dzięki za pomoc!

pozdrawiam
bela
Myślę, że trochę chcesz wynaleźć znów koło. Symfony ma już tłumaczenia i lokalizację wbudowane. Przeczytaj ten artykuł to się rozjaśni.
http://www.symfony-project.org/jobeet/1_4/Doctrine/en/19
joshuaBE
Dzięki za odpowiedź. Już wcześniej czytałem, to co mi podałeś. Jest tam przykład z tłumaczonymi na różne języki kategoriami, ale każda kategoria posiada zawsze ten sam zbiór danych, niezależnie od wybranego języka. Jeśli skorzystam z I18n w moim schemacie dla tabeli artykułów, to utworzy mi się nowa tabela, która będzie się odwoływała do pierwotnej tabeli za pomocą pary id-lang. Ale nigdy nie będzie u mnie sytuacji, w której artykuł o tym samym numerze ID będzie posiadał kilka języków. Zawsze jeden artykuł, o konkretnym numerze ID będzie należał do jednego języka. Czy dałoby się uzyskać dokładnie taki sam efekt jak ten ze schematu z mojego wcześniejszego postu, ale z użyciem wbudowanych funkcji symfony?
joshuaBE
Niestety, nie znajduje tam odpowiedzi na mój problem
Crozin
Robisz wszystko tak jakbyś miał stronę w jednym języku po czym dodajesz kolumnę na język. Przy wybieraniu artykułów nakładasz warunek WHERE article.language = :language
Tyle.
joshuaBE
Czyli właściwie tak jak już mam smile.gif Ok, dzięki

Jeszcze tylko jedno pytanie:

Mam teraz taki routing:

CODE

default_lang_article:
url: /guide/:slug
class: sfDoctrineRoute
options: { model: JbArticle, type: object, method_for_query: retrieveDefaultLangArticle }
param: { module: article, action: show }

article:
url: /:lang/guide/:slug
class: sfDoctrineRoute
options: { model: JbArticle, type: object }
param: { module: article, action: show }
requirements: { lang: (?: pl|de) }


Czy dałoby się tłumaczyć słowo guide w roucie 'article' na różne języki w zależności od zmiennej 'lang', nie tworząc przy tym routa dla każdego języka? Jesli tak, to jak?
destroyerr
Tak, dałoby się. Najszybciej będzie skorzystać z pluginu, a takie na pewno są.
puc
możesz skorzystać z dynamicznego tworzenia routingu

  1.  
  2. $route=new sfRoute('translate_url',array('module' => 'moduleName', 'action' => 'showPage'));
  3. $routing->prependRoute('route_name', $route);


w factories.yml musisz zmienić wpis:
  1. all:
  2. routing:
  3. class: myRouting
  4. param:
  5. generate_shortest_url: true
  6. extra_parameters_as_query_string: true


i stworzyć odpowiednią klasę oczywiście w której umieść odpowiedni dla ciebie kod np:

  1. class myRouting extends sfPatternRouting{
  2. public function initialize(sfEventDispatcher $dispatcher, sfCache $cache = null, $options = array()){
  3. parent::initialize($dispatcher, $cache, $options);
  4. }
  5.  
  6. static public function listenToRoutingLoadConfigurationEvent(sfEvent $event){
  7. $routing = $event->getSubject();
  8. foreach(Doctrine::getTable('Pages')->getPages() as $page){
  9. eval('$route_name = $page->link'.$lang.';');
  10. $route=new sfRoute($route_name,array('module' => 'master_controller', 'action' => 'showPage', 'id'=>$page->id));
  11. $routing->prependRoute('custom_route_'.$page->id, $route);
  12. }
  13. }
  14.  
  15. }
  16. }
destroyerr
@puc ale Twój sposób jest bezsensowny, routing służy właśnie do tego, żeby nie pobierać wszystkich obiektów z bazy (i to naraz).
Do tego jeszcze ten eval potwierdza, że kod jest marnej jakości.
puc
to był przykład napisany 'na kolanie' - on nie miał być skopiowany (...)"umieść odpowiedni dla ciebie kod"(...).
z drugiej strony jak w takim razie tworzyć dynamicznie routing nie używając prependRoute?
joshuaBE
Hej,

zrobiłem w ten sposób:

routing.yml:

CODE
article:
url: /:sf_culture/:guide/:slug
class: sfDoctrineRoute
options: { model: JbArticle, type: object, method_for_query: retrieveLangArticle }
param: { module: article, action: show }
requirements: { sf_culture: (?tongue.gifl|de) }

default_lang_article:
url: /:guide/:slug
class: sfDoctrineRoute
options: { model: JbArticle, type: object, method_for_query: retrieveLangArticle }
param: { module: article, action: show, sf_culture: en, guide: guide }


filtr:
  1. class sfArticleModuleTranslationFilter extends sfFilter
  2. {
  3. public function execute($filterChain)
  4. {
  5. if ($this->isFirstCall())
  6. {
  7. $guide = $this->context->getRequest()->getParameter('guide');
  8.  
  9. if($guide != $this->context->getI18N()->__('guide'))
  10. {
  11. $this->context->getController()->forward('default', 'error404');
  12. throw new sfStopException();
  13. }
  14. }
  15. $filterChain->execute();
  16. }
  17. }


A linki tworzone tak:
  1. echo link_to('click', 'article/show?slug=test&guide='.__('guide')); //dla linków do artykułów w danym języku
  2. echo link_to('click', 'article/show?slug=test&sf_culture=en&guide='.__('guide', null, null, 'en')); //dla linków do artykułów z innego języka


Musiałem też zmodyfikować helper __(), żeby przyjmował 4 parametr:
  1. function __($text, $args = array(), $catalogue = 'messages', $culture = null)
  2. {
  3. if (sfConfig::get('sf_i18n'))
  4. {
  5. if (!empty($culture))
  6. {
  7. $user = sfContext::getInstance()->getUser();
  8. $real_culture = $user->getCulture();
  9. $user->setCulture($culture);
  10. }
  11. $message = sfContext::getInstance()->getI18N()->__($text, $args, $catalogue);
  12. if (!empty($culture))
  13. {
  14. # back to the real culture
  15. $user->setCulture($real_culture);
  16. }
  17. return $message;
  18. }
  19. //...



Nie wiem czy to jest dobre rozwiązanie, ale ogólnie działa smile.gif
To jest wersja lo-fi głównej zawartości. Aby zobaczyć pełną wersję z większą zawartością, obrazkami i formatowaniem proszę kliknij tutaj.
Invision Power Board © 2001-2025 Invision Power Services, Inc.