PageRenderTime 51ms CodeModel.GetById 19ms RepoModel.GetById 1ms app.codeStats 0ms

/system/cms/plugins/theme.php

https://github.com/asalem/pyrocms
PHP | 667 lines | 446 code | 45 blank | 176 comment | 7 complexity | aec39f3b4fd2f20c94075da132320be4 MD5 | raw file
Possible License(s): CC-BY-3.0, BSD-3-Clause, CC0-1.0, LGPL-2.1, MPL-2.0-no-copyleft-exception, MIT
  1. <?php defined('BASEPATH') or exit('No direct script access allowed');
  2. /**
  3. * Theme Plugin
  4. *
  5. * Load partials and access data
  6. *
  7. * @author PyroCMS Dev Team
  8. * @package PyroCMS\Core\Plugins
  9. */
  10. class Plugin_Theme extends Plugin
  11. {
  12. public $version = '1.1.0';
  13. public $name = array(
  14. 'en' => 'Theme',
  15. );
  16. public $description = array(
  17. 'en' => 'Load and display theme assets.',
  18. 'el' => 'Φορτώνει και προβάλλει πόρους του θέματος εμφάνισης.',
  19. 'fa' => 'بارگزاری و نمایش asset های قالب ها',
  20. 'fr' => 'Permet de charger et d\'afficher les différentes ressources du thème.',
  21. 'it' => 'Carica e mostra gli asset del tema'
  22. );
  23. /**
  24. * Returns a PluginDoc array that PyroCMS uses
  25. * to build the reference in the admin panel
  26. *
  27. * All options are listed here but refer
  28. * to the Blog plugin for a larger example
  29. *
  30. * @todo fill the array with details about this plugin, then uncomment the return value.
  31. *
  32. * @return array
  33. */
  34. public function _self_doc()
  35. {
  36. $info = array(
  37. 'path' => array(// the name of the method you are documenting
  38. 'description' => array(// a single sentence to explain the purpose of this method
  39. 'en' => 'Outputs the path to the theme relative to the web root.'
  40. ),
  41. 'single' => true,// will it work as a single tag?
  42. 'double' => false,// how about as a double tag?
  43. 'variables' => '',// list all variables available inside the double tag. Separate them|like|this
  44. 'attributes' => array(),
  45. ),// end path method
  46. 'partial' => array(// the name of the method you are documenting
  47. 'description' => array(// a single sentence to explain the purpose of this method
  48. 'en' => 'Outputs a theme partial file at the location of this tag (usually in your layout file).'
  49. ),
  50. 'single' => true,// will it work as a single tag?
  51. 'double' => false,// how about as a double tag?
  52. 'variables' => '',// list all variables available inside the double tag. Separate them|like|this
  53. 'attributes' => array(
  54. 'name' => array(// this is the order-dir="asc" attribute
  55. 'type' => 'text',// Can be: slug, number, flag, text, array, any.
  56. 'flags' => '',// flags are predefined values like this.
  57. 'default' => '',// attribute defaults to this if no value is given
  58. 'is_required' => true,// is this attribute required?
  59. ),
  60. ),
  61. ),// end partial method
  62. 'variables' => array(
  63. 'description' => array(
  64. 'en' => 'Set and display temporary variables.'
  65. ),
  66. 'single' => true,
  67. 'double' => false,
  68. 'variables' => '',
  69. 'attributes' => array(
  70. 'name' => array(
  71. 'type' => 'text',
  72. 'flags' => '',
  73. 'default' => '',
  74. 'is_required' => true,
  75. ),
  76. 'value' => array(
  77. 'type' => 'text',
  78. 'flags' => '',
  79. 'default' => '',
  80. 'is_required' => false,
  81. ),
  82. ),
  83. ),// end variables method
  84. 'favicon' => array(
  85. 'description' => array(
  86. 'en' => 'Display a favicon for your site.'
  87. ),
  88. 'single' => true,
  89. 'double' => false,
  90. 'variables' => '',
  91. 'attributes' => array(
  92. 'file' => array(
  93. 'type' => 'text',
  94. 'flags' => '',
  95. 'default' => 'favicon.ico',
  96. 'is_required' => false,
  97. ),
  98. 'rel' => array(
  99. 'type' => 'text',
  100. 'flags' => '',
  101. 'default' => 'shortcut icon',
  102. 'is_required' => false,
  103. ),
  104. 'sizes' => array(
  105. 'type' => 'text',
  106. 'flags' => '',
  107. 'default' => '',
  108. 'is_required' => false,
  109. ),
  110. 'type' => array(
  111. 'type' => 'text',
  112. 'flags' => '',
  113. 'default' => 'image/x-icon',
  114. 'is_required' => false,
  115. ),
  116. 'xhtml' => array(
  117. 'type' => 'flag',
  118. 'flags' => 'Y|N',
  119. 'default' => 'N',
  120. 'is_required' => false,
  121. ),
  122. ),
  123. ),// end favicon method
  124. 'lang' => array(
  125. 'description' => array(
  126. 'en' => 'Output a translated string from the language file specified by [lang]. Use [default] to output a fallback string.'
  127. ),
  128. 'single' => true,
  129. 'double' => false,
  130. 'variables' => '',
  131. 'attributes' => array(
  132. 'lang' => array(
  133. 'type' => 'text',
  134. 'flags' => '',
  135. 'default' => '',
  136. 'is_required' => true,
  137. ),
  138. 'line' => array(
  139. 'type' => 'text',
  140. 'flags' => '',
  141. 'default' => '',
  142. 'is_required' => true,
  143. ),
  144. 'default' => array(
  145. 'type' => 'text',
  146. 'flags' => '',
  147. 'default' => '',
  148. 'is_required' => false,
  149. ),
  150. ),
  151. ),// end lang method
  152. 'css' => array(
  153. 'description' => array(
  154. 'en' => 'Load a CSS file from the theme\'s css folder',
  155. ),
  156. 'single' => true,
  157. 'double' => false,
  158. 'variables' => '',
  159. 'attributes' => array(
  160. 'file' => array(
  161. 'type' => 'text',
  162. 'flags' => '',
  163. 'default' => '',
  164. 'is_required' => true,
  165. ),
  166. 'title' => array(
  167. 'type' => 'text',
  168. 'flags' => '',
  169. 'default' => '',
  170. 'is_required' => false,
  171. ),
  172. 'media' => array(
  173. 'type' => 'text',
  174. 'flags' => '',
  175. 'default' => '',
  176. 'is_required' => false,
  177. ),
  178. 'type' => array(
  179. 'type' => 'text',
  180. 'flags' => '',
  181. 'default' => 'text/css',
  182. 'is_required' => false,
  183. ),
  184. 'rel' => array(
  185. 'type' => 'text',
  186. 'flags' => '',
  187. 'default' => 'stylesheet',
  188. 'is_required' => false,
  189. ),
  190. ),
  191. ),// end css method
  192. 'css_path' => array(
  193. 'description' => array(
  194. 'en' => 'Output the filesystem path to the specified CSS file.',
  195. ),
  196. 'single' => true,
  197. 'double' => false,
  198. 'variables' => '',
  199. 'attributes' => array(
  200. 'file' => array(
  201. 'type' => 'text',
  202. 'flags' => '',
  203. 'default' => '',
  204. 'is_required' => true,
  205. ),
  206. ),
  207. ),// end css_path method
  208. 'css_url' => array(
  209. 'description' => array(
  210. 'en' => 'Output the url to the specified CSS file.',
  211. ),
  212. 'single' => true,
  213. 'double' => false,
  214. 'variables' => '',
  215. 'attributes' => array(
  216. 'file' => array(
  217. 'type' => 'text',
  218. 'flags' => '',
  219. 'default' => '',
  220. 'is_required' => true,
  221. ),
  222. ),
  223. ),// end css_url method
  224. 'image' => array(
  225. 'description' => array(
  226. 'en' => 'Output a theme image from the theme\'s img folder. Extra attributes can be used to set the class or etc.',
  227. ),
  228. 'single' => true,
  229. 'double' => false,
  230. 'variables' => '',
  231. 'attributes' => array(
  232. 'file' => array(
  233. 'type' => 'text',
  234. 'flags' => '',
  235. 'default' => '',
  236. 'is_required' => true,
  237. ),
  238. 'alt' => array(
  239. 'type' => 'text',
  240. 'flags' => '',
  241. 'default' => 'the file name',
  242. 'is_required' => false,
  243. ),
  244. 'any' => array(
  245. 'type' => 'text',
  246. 'flags' => '',
  247. 'default' => '',
  248. 'is_required' => false,
  249. ),
  250. ),
  251. ),// end image method
  252. 'image_path' => array(
  253. 'description' => array(
  254. 'en' => 'Output the filesystem path to the specified image file.',
  255. ),
  256. 'single' => true,
  257. 'double' => false,
  258. 'variables' => '',
  259. 'attributes' => array(
  260. 'file' => array(
  261. 'type' => 'text',
  262. 'flags' => '',
  263. 'default' => '',
  264. 'is_required' => true,
  265. ),
  266. ),
  267. ),// end image_path method
  268. 'image_url' => array(
  269. 'description' => array(
  270. 'en' => 'Output the url to the specified image file.',
  271. ),
  272. 'single' => true,
  273. 'double' => false,
  274. 'variables' => '',
  275. 'attributes' => array(
  276. 'file' => array(
  277. 'type' => 'text',
  278. 'flags' => '',
  279. 'default' => '',
  280. 'is_required' => true,
  281. ),
  282. ),
  283. ),// end image_url method
  284. 'js' => array(
  285. 'description' => array(
  286. 'en' => 'Include a JavaScript file from the theme\'s js folder',
  287. ),
  288. 'single' => true,
  289. 'double' => false,
  290. 'variables' => '',
  291. 'attributes' => array(
  292. 'file' => array(
  293. 'type' => 'text',
  294. 'flags' => '',
  295. 'default' => '',
  296. 'is_required' => true,
  297. ),
  298. ),
  299. ),// end js method
  300. 'js_path' => array(
  301. 'description' => array(
  302. 'en' => 'Output the filesystem path to the specified js file.',
  303. ),
  304. 'single' => true,
  305. 'double' => false,
  306. 'variables' => '',
  307. 'attributes' => array(
  308. 'file' => array(
  309. 'type' => 'text',
  310. 'flags' => '',
  311. 'default' => '',
  312. 'is_required' => true,
  313. ),
  314. ),
  315. ),// end js_path method
  316. 'js_url' => array(
  317. 'description' => array(
  318. 'en' => 'Output the url to the specified js file.',
  319. ),
  320. 'single' => true,
  321. 'double' => false,
  322. 'variables' => '',
  323. 'attributes' => array(
  324. 'file' => array(
  325. 'type' => 'text',
  326. 'flags' => '',
  327. 'default' => '',
  328. 'is_required' => true,
  329. ),
  330. ),
  331. ),// end js_url method
  332. );
  333. return $info;
  334. }
  335. /**
  336. * Partial
  337. *
  338. * Loads a theme partial
  339. *
  340. * Usage:
  341. *
  342. * {{ theme:partial name="header" any_random_data="foo" }}
  343. *
  344. * @return string The final rendered partial view.
  345. */
  346. public function partial()
  347. {
  348. $attributes = $this->attributes();
  349. if (empty($attributes['name'])) {
  350. throw new Exception('Attributes must have a name="" attribute.');
  351. }
  352. $name = $attributes['name'];
  353. unset($attributes['name']);
  354. $path = $this->load->get_var('template_views');
  355. $data = array_merge($this->load->get_vars(), $attributes);
  356. $string = $this->load->file($path . 'partials/' . $name . '.html', true);
  357. return $this->parser->parse_string($string, $data, true, true);
  358. }
  359. /**
  360. * Path
  361. *
  362. * Get the path to the theme
  363. *
  364. * Usage:
  365. *
  366. * {{ theme:assets }}
  367. *
  368. * @return string The rendered assets (CSS/Js) for the theme.
  369. */
  370. public function assets()
  371. {
  372. return Asset::render('theme');
  373. }
  374. /**
  375. * Path
  376. *
  377. * Get the path to the theme
  378. *
  379. * Usage:
  380. *
  381. * {{ theme:path }}
  382. *
  383. * @return string The path to the theme (relative to web root).
  384. */
  385. public function path()
  386. {
  387. $path = rtrim($this->load->get_var('template_views'), '/');
  388. return preg_replace('#(\/views(\/web|\/mobile)?)$#', '', $path) . '/';
  389. }
  390. /**
  391. * Theme CSS
  392. *
  393. * Insert a CSS tag with location based for url or path from the theme or module
  394. *
  395. * Usage:
  396. *
  397. * {{ theme:css file="" }}
  398. *
  399. * @return string The link HTML tag for the stylesheets.
  400. */
  401. public function css()
  402. {
  403. $file = $this->attribute('file');
  404. $title = $this->attribute('title', ''); // CodeIgniter stupidly checks for '' not empty
  405. $media = $this->attribute('media', ''); // CodeIgniter stupidly checks for '' not empty
  406. $type = $this->attribute('type', 'text/css');
  407. $rel = $this->attribute('rel', 'stylesheet');
  408. return link_tag($this->css_url($file), $rel, $type, $title, $media);
  409. }
  410. /**
  411. * Theme CSS URL
  412. *
  413. * Usage:
  414. *
  415. * {{ theme:css_url file="" }}
  416. *
  417. * @return string The CSS URL
  418. */
  419. public function css_url()
  420. {
  421. $file = $this->attribute('file');
  422. return Asset::get_filepath_css($file, true);
  423. }
  424. /**
  425. * Theme CSS PATH
  426. *
  427. * Usage:
  428. * {{ theme:css_path file="" }}
  429. *
  430. * @return string The CSS location path
  431. */
  432. public function css_path()
  433. {
  434. $file = $this->attribute('file');
  435. return Asset::get_filepath_css($file, false);
  436. }
  437. /**
  438. * Theme Image
  439. *
  440. * Insert a image tag with location based for url or path from the theme or module
  441. *
  442. * Usage:
  443. *
  444. * {{ theme:image file="" }}
  445. *
  446. * @return string An empty string or the image tag.
  447. */
  448. public function image()
  449. {
  450. $file = $this->attribute('file');
  451. $alt = $this->attribute('alt', $file);
  452. $attributes = $this->attributes();
  453. foreach (array('file', 'alt') as $key) {
  454. if (isset($attributes[$key])) {
  455. unset($attributes[$key]);
  456. } elseif ($key == 'file') {
  457. return '';
  458. }
  459. }
  460. try {
  461. return Asset::img($file, $alt, $attributes);
  462. } catch (Asset_Exception $e) {
  463. return '';
  464. }
  465. }
  466. /**
  467. * Theme Image URL
  468. *
  469. * Usage:
  470. *
  471. * {{ theme:image_url file="" }}
  472. *
  473. * @return string The image URL
  474. */
  475. public function image_url()
  476. {
  477. $file = $this->attribute('file');
  478. return Asset::get_filepath_img($file, true);
  479. }
  480. /**
  481. * Theme Image PATH
  482. *
  483. * Usage:
  484. *
  485. * {{ theme:image_path file="" }}
  486. *
  487. * @return string The image location path
  488. */
  489. public function image_path()
  490. {
  491. $file = $this->attribute('file');
  492. return BASE_URI . Asset::get_filepath_img($file, false);
  493. }
  494. /**
  495. * Theme JS
  496. *
  497. * Insert a JS tag with location based for url or path from the theme or module
  498. *
  499. * Usage:
  500. *
  501. * {{ theme:js file="" }}
  502. *
  503. * @param string $return Not used
  504. *
  505. * @return string An empty string or the script tag.
  506. */
  507. public function js($return = '')
  508. {
  509. $file = $this->attribute('file');
  510. return '<script src="' . $this->js_url($file) . '" type="text/javascript"></script>';
  511. }
  512. /**
  513. * Theme JS URL
  514. *
  515. * Usage:
  516. *
  517. * {{ theme:js_url file="" }}
  518. *
  519. * @return string The javascript asset URL.
  520. */
  521. public function js_url()
  522. {
  523. $file = $this->attribute('file');
  524. return Asset::get_filepath_js($file, true);
  525. }
  526. /**
  527. * Theme JS PATH
  528. *
  529. * Usage:
  530. *
  531. * {{ theme:js_path file="" }}
  532. *
  533. * @return string The javascript asset location path.
  534. */
  535. public function js_path()
  536. {
  537. $file = $this->attribute('file');
  538. return BASE_URI . Asset::get_filepath_js($file, false);
  539. }
  540. /**
  541. * Set and get theme variables
  542. *
  543. * Usage:
  544. *
  545. * {{ theme:variables name="foo" }}
  546. *
  547. * @return string The variable value.
  548. */
  549. public function variables()
  550. {
  551. if (!isset($variables)) {
  552. static $variables = array();
  553. }
  554. $name = $this->attribute('name');
  555. $value = $this->attribute('value');
  556. if ($value !== null) {
  557. $variables[$name] = $value;
  558. return;
  559. }
  560. return $variables[$name];
  561. }
  562. /**
  563. * Theme Favicon
  564. *
  565. * Insert a link tag for favicon from your theme
  566. *
  567. * Specs:
  568. *
  569. * http://www.w3.org/TR/html5/links.html#rel-icon
  570. *
  571. * Usage:
  572. *
  573. * {{ theme:favicon file="" [rel="foo"] [type="bar"] [sizes="16x16 72x72 …"] }}
  574. *
  575. * @return string The link HTML tag for the favicon.
  576. */
  577. public function favicon()
  578. {
  579. $this->load->library('asset');
  580. $file = Asset::get_filepath_img($this->attribute('file', 'favicon.ico'), true);
  581. $rel = $this->attribute('rel', 'shortcut icon');
  582. $sizes = $this->attribute('sizes', '');
  583. $type = $this->attribute('type', 'image/x-icon');
  584. $is_xhtml = str_to_bool($this->attribute('xhtml', true));
  585. $link = '<link ';
  586. $link .= 'href="' . $file . '" ';
  587. $link .= 'rel="' . $rel . '" ';
  588. $link .= $sizes ? 'sizes="' . $sizes . '" ' : '';
  589. $link .= 'type="' . $type . '" ';
  590. $link .= ($is_xhtml ? '/' : '') . '>';
  591. return $link;
  592. }
  593. /**
  594. * Theme Language line
  595. *
  596. * Fetch a single line of text from the language array
  597. *
  598. * Usage:
  599. *
  600. * {{ theme:lang lang="theme" line="theme_title" [default="PyroCMS"] }}
  601. *
  602. * @return string.
  603. */
  604. public function lang()
  605. {
  606. $lang_file = $this->attribute('lang');
  607. $line = $this->attribute('line');
  608. $default = $this->attribute('default');
  609. // Return an empty string as the attribute LINE is missing
  610. if ( ! isset($line)) {
  611. return "";
  612. }
  613. $deft_lang = CI::$APP->config->item('language');
  614. if ($lang = Modules::load_file($lang_file . '_lang', CI::$APP->template->get_theme_path() . '/language/' . $deft_lang . '/', 'lang')) {
  615. CI::$APP->lang->language = array_merge(CI::$APP->lang->language, $lang);
  616. CI::$APP->lang->is_loaded[] = $lang_file . '_lang' . EXT;
  617. unset($lang);
  618. }
  619. $value = $this->lang->line($line);
  620. return $value ? $value : $default;
  621. }
  622. }