langswitcher.php 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180
  1. <?php
  2. namespace Grav\Plugin;
  3. use Composer\Autoload\ClassLoader;
  4. use Grav\Common\Cache;
  5. use Grav\Common\Language\Language;
  6. use Grav\Common\Language\LanguageCodes;
  7. use Grav\Common\Page\Interfaces\PageInterface;
  8. use Grav\Common\Page\Page;
  9. use Grav\Common\Page\Pages;
  10. use \Grav\Common\Plugin;
  11. class LangSwitcherPlugin extends Plugin
  12. {
  13. /**
  14. * @return array
  15. */
  16. public static function getSubscribedEvents()
  17. {
  18. return [
  19. 'onPluginsInitialized' => [
  20. ['autoload', 100001],
  21. ['onPluginsInitialized', 0]
  22. ]
  23. ];
  24. }
  25. /**
  26. * [onPluginsInitialized:100000] Composer autoload.
  27. *
  28. * @return ClassLoader
  29. */
  30. public function autoload()
  31. {
  32. return require __DIR__ . '/vendor/autoload.php';
  33. }
  34. /**
  35. * Initialize configuration
  36. */
  37. public function onPluginsInitialized()
  38. {
  39. if ($this->isAdmin()) {
  40. $this->active = false;
  41. return;
  42. }
  43. $this->enable([
  44. 'onTwigInitialized' => ['onTwigInitialized', 0],
  45. 'onTwigTemplatePaths' => ['onTwigTemplatePaths', 0],
  46. 'onTwigSiteVariables' => ['onTwigSiteVariables', 0]
  47. ]);
  48. }
  49. /** Add the native_name function */
  50. public function onTwigInitialized()
  51. {
  52. $this->grav['twig']->twig()->addFunction(
  53. new \Twig_SimpleFunction('native_name', function($key) {
  54. return LanguageCodes::getNativeName($key);
  55. })
  56. );
  57. }
  58. /**
  59. * Add current directory to twig lookup paths.
  60. */
  61. public function onTwigTemplatePaths()
  62. {
  63. $this->grav['twig']->twig_paths[] = __DIR__ . '/templates';
  64. }
  65. /**
  66. * Generate localized route based on the translated slugs found through the pages hierarchy
  67. */
  68. protected function getTranslatedUrl($lang, $path)
  69. {
  70. /** @var Language $language */
  71. $url = null;
  72. /** @var Pages $pages */
  73. $pages = $this->grav['pages'];
  74. /** @var Language $language */
  75. $language = $this->grav['language'];
  76. $language->init();
  77. $language->setActive($lang);
  78. $pages->reset();
  79. $page = $pages->get($path);
  80. if ($page) {
  81. $url = $page->url();
  82. }
  83. return $url;
  84. }
  85. /**
  86. * Set needed variables to display Langswitcher.
  87. */
  88. public function onTwigSiteVariables()
  89. {
  90. /** @var PageInterface $page */
  91. $page = $this->grav['page'];
  92. /** @var Pages $pages */
  93. $pages = $this->grav['pages'];
  94. /** @var Cache $cache */
  95. $cache = $this->grav['cache'];
  96. $data = new \stdClass;
  97. $data->page_route = $page->rawRoute();
  98. if ($page->home()) {
  99. $data->page_route = '/';
  100. }
  101. $translated_cache_key = md5('translated_cache_key'.$data->page_route.$pages->getSimplePagesHash());
  102. $languages = $this->grav['language']->getLanguages();
  103. $data->languages = $languages;
  104. if ($this->config->get('plugins.langswitcher.untranslated_pages_behavior') !== 'none') {
  105. $translated_pages = [];
  106. foreach ($languages as $language) {
  107. $translated_pages[$language] = null;
  108. $page_name_without_ext = substr($page->name(), 0, -(strlen($page->extension())));
  109. $translated_page_path = $page->path() . DS . $page_name_without_ext . '.' . $language . '.md';
  110. if (!file_exists($translated_page_path) and $language == $this->grav['language']->getDefault()) {
  111. $translated_page_path = $page->path() . DS . $page_name_without_ext . '.md';
  112. }
  113. if (file_exists($translated_page_path)) {
  114. $translated_page = new Page();
  115. $translated_page->init(new \SplFileInfo($translated_page_path), $language . '.md');
  116. $translated_pages[$language] = $translated_page;
  117. }
  118. }
  119. $data->translated_pages = $translated_pages;
  120. }
  121. $language = $this->grav['language'];
  122. $active = $language->getActive() ?? $language->getDefault();
  123. if ($this->config->get('plugins.langswitcher.translated_urls', true)) {
  124. $data->translated_routes = $cache->fetch($translated_cache_key) ?: [];
  125. if (empty($data->translated_routes)) {
  126. $translate_langs = $data->languages;
  127. if (($key = array_search($active, $translate_langs)) !== false) {
  128. $data->translated_routes[$active] = $page->url();
  129. unset($translate_langs[$key]);
  130. }
  131. foreach ($translate_langs as $lang) {
  132. $data->translated_routes[$lang] = $this->getTranslatedUrl($lang, $page->path());
  133. if (is_null($data->translated_routes[$lang])) {
  134. $data->translated_routes[$lang] = $data->page_route;
  135. }
  136. }
  137. // Reset pages to current active language
  138. $language->init();
  139. $language->setActive($active);
  140. $this->grav['pages']->reset();
  141. $cache->save($translated_cache_key, $data->translated_routes);
  142. }
  143. }
  144. $data->current = $language->getLanguage();
  145. $this->grav['twig']->twig_vars['langswitcher'] = $this->grav['langswitcher'] = $data;
  146. if ($this->config->get('plugins.langswitcher.built_in_css')) {
  147. $this->grav['assets']->add('plugin://langswitcher/css/langswitcher.css');
  148. }
  149. }
  150. public function getNativeName($code) {
  151. }
  152. }