/** * Creates a stylesheet link with LESS support * * @param string $style file name * @param array $attributes default attributes * @param bool $index include the index page * @param array $imports compare file date for these too, CSS and LESS in style @import * @return string */ public static function style($file, array $attributes = null, $index = false, $imports = null) { $imports = (array) $imports; // Compile only .less files if (substr_compare($file, '.less', -5, 5, false) === 0) { $css = substr_replace($file, 'css', -4); $compiled = is_file($css) ? filemtime($css) : 0; try { // Check if imported files have changed $compile = filemtime($file) > $compiled; if (!$compile && !empty($imports)) { foreach ($imports as $import) { if (filemtime($import) > $compiled) { $compile = true; break; } } } // Compile LESS if ($compile) { $compiler = new Less($file); file_put_contents($css, $compiler->parse()); } $file = $css; } catch (Exception $e) { Kohana::$log->add(Log::ERROR, __METHOD__ . ': Error compiling LESS file ' . $file . ', ' . $e->getMessage()); } } return HTML::style($file . '?' . filemtime($file), $attributes, $index); }
public function __construct() { global $globals; call_user_func_array('parent::__construct', func_get_args()); if ($globals->debug) { Less::make(); } }
/** * [assets description] * @param Array $assets * @return String js or css */ public function compile($assets, $type) { $self = $this; $rewriteCssUrls = function ($content, $asset) use($self) { $source_dir = dirname($asset["file"]); $root_dir = $self->app['docs_root']; $csspath = ""; if (strlen($root_dir) < strlen($source_dir)) { $csspath = '/' . trim(str_replace($root_dir, '', $source_dir), "/") . "/"; } else { // todo } $offset = 0; while (($pos = strpos($content, 'url(', $offset)) !== false) { if (($urlend = strpos($content, ')', $pos)) !== false) { $path = trim(str_replace(array('"', "'"), "", substr($content, $pos + 4, $urlend - ($pos + 4)))); if (!preg_match("#^(http|/|data\\:)#", trim($path))) { $content = str_replace($path, $csspath . $path, $content); } } $offset = $pos + 1; } return $content; }; $output = array(); foreach ((array) $assets as $file) { $asset = array("ext" => pathinfo($file, PATHINFO_EXTENSION), "file" => $file); $ext = $asset['ext'] == "scss" || $asset['ext'] == "less" ? "css" : $asset['ext']; $content = ''; if (strpos($file, ':') !== false && ($____file = $this->app->path($file))) { $asset['file'] = $file = $____file; } if ($ext != $type) { continue; } switch ($asset['ext']) { case 'js': $content = @file_get_contents($file); break; case 'scss': case 'less': case 'css': switch ($asset['ext']) { case 'scss': $content = \Sass::parse($file); break; case 'less': $content = \Less::parse($file); break; default: $content = @file_get_contents($file); } $content = $rewriteCssUrls($content, $asset); break; default: continue; } $output[] = $content; } return implode("", $output); }
#!/usr/bin/php -q <?php /*************************************************************************** * Copyright (C) 2004-2012 Binet Réseau * * http://br.binets.fr/ * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the Free Software * * Foundation, Inc., * * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * ***************************************************************************/ /* * When not in debug mode, this script helps to rebuild * the css & tpl files after a fetch */ require_once dirname(__FILE__) . '/connect.db.inc.php'; echo "Less to Css \n"; Less::make(); echo "Purging tpl's spool \n"; exec('rm ../spool/templates_c/* -f'); // vim:set et sw=4 sts=4 sws=4 foldmethod=marker enc=utf-8:
" /> <title><?php echo $page_title ? HTML::chars($page_title) . ' | ' : ''; echo Kohana::$config->load('site.site_name'); ?> </title> <link rel="icon" type="image/png" href="/ui/favicon.png" /> <?php foreach ($styles as $file => $attributes) { echo HTML::style($file, $attributes), "\n"; } ?> <?php foreach ($skins as $skin_name => $available_skin) { echo Less::style($available_skin['path'], array('title' => $skin_name, 'rel' => $skin_name == $skin ? 'stylesheet' : 'alternate stylesheet'), false, $skin_imports); } ?> <?php echo HTML::style('ui/site.css'); ?> <?php echo HTML::script(Kohana::$environment == Kohana::PRODUCTION ? 'js/head.min.js' : 'js/head.js'); ?> <?php /*echo HTML::script_source(" head .js( { 'jquery': 'http://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js' }, { 'jquery-ui': 'http://ajax.googleapis.com/ajax/libs/jqueryui/1.8.4/jquery-ui.min.js' },
/** * Build the theme : copy every resource files in themes/{themename} * * @param boolean $force If set to true, the theme will be rebuilt without condition * * @return boole True if the theme has been built, false it it has been taken from cache */ public function build($force = false) { if ($this->getDefinition('extends')) { if (Theme::get($this->getDefinition('extends'))) { Theme::get($this->getDefinition('extends'))->build($force); } } $build = false; if ($force) { $build = true; } if (!file_exists($this->getStaticDir())) { mkdir($this->getStaticDir(), 0755, true); $build = true; } if (!$build) { $dest = $this->getStaticCssFile(); if (!is_file($dest)) { $build = true; } else { // Get all files in less/ $files = App::fs()->find($this->getLessDirname(), '*.less'); $lastUpdate = filemtime($dest); foreach ($files as $file) { if (filemtime($file) > $lastUpdate) { $build = true; break; } } } } if ($build) { // Build the theme => Copy each accessible files in static dir foreach (glob($this->getRootDir() . '*') as $elt) { if (!in_array(basename($elt), array('views', 'start.php'))) { App::fs()->copy($elt, $this->getStaticDir()); } } // In the main less file, replace the editable vars by their customized values $values = $this->getVariablesCustomValues(); $precompiledLess = preg_replace_callback(self::EDITABLE_VARS_PATTERN, function ($m) use($values) { return '@' . $m[1] . ' : ' . (isset($values[$m[1]]) ? $values[$m[1]] : $m[2]) . ';'; }, file_get_contents($this->getBaseLessFile())); file_put_contents($this->getStaticLessFile(), $precompiledLess); Less::compile($this->getStaticLessFile(), $this->getStaticCssFile()); } return $build; }
/** * Return the URL of a public CSS file, * or the URL of the directory containing public CSS files if $basename is empty * * @param string $basename The Less file basename * * @return string The URL */ public function getCssUrl($basename = "") { $cssUrl = $this->getStaticUrl() . 'css/'; if (empty($basename)) { return $cssUrl; } else { $privateFilename = $this->getLessDir() . $basename; $cssBasename = preg_replace('/\\.less$/', '.css', $basename); $publicFilename = $this->getPublicCssDir() . $cssBasename; if (is_file($privateFilename)) { Event::on('built-less', function (Event $event) use($privateFilename) { if ($event->getData('source') === $privateFilename) { // Copy all static files except less and JS foreach (glob($this->getStaticDir() . '*') as $elt) { if (!in_array(basename($elt), array('less', 'js'))) { App::fs()->copy($elt, $this->getPublicStaticDir()); } } } }); Less::compile($privateFilename, $publicFilename); } return $cssUrl . $cssBasename . '?' . filemtime($publicFilename); } }
/** * Destroy controller. */ public function after() { if ($this->_request_type !== Controller::REQUEST_INITIAL) { // AJAX and HMVC requests $this->response->body((string) $this->response->body()); } else { if ($this->auto_render) { // Normal requests // Stylesheets $styles = array('ui/jquery-ui.css', 'http://fonts.googleapis.com/css?family=Terminal+Dosis'); // Skins $selected_skin = $this->session->get('skin', 'blue'); // Less files needed to build a skin $less_imports = array('ui/mixin.less', 'ui/anqh.less'); $skins = array(HTML::style('static/css/bootstrap.css'), HTML::style('static/css/bootstrap-responsive.css')); foreach (array('blue') as $skin) { $skinsi[] = Less::style('ui/' . $skin . '.less', array('title' => $skin, 'rel' => $skin == $selected_skin ? 'stylesheet' : 'alternate stylesheet'), false, $less_imports); } // Footer $section = new View_Events_List(); $section->class .= ' span4'; $section->title = __('New events'); $section->events = Model_Event::factory()->find_new(10); Widget::add('footer', $section); $section = new View_Topics_List(); $section->class .= ' span4'; $section->title = __('New posts'); $section->topics = Model_Forum_Topic::factory()->find_by_latest_post(10); Widget::add('footer', $section); $section = new View_Blogs_List(); $section->class .= ' span4'; $section->title = __('New blogs'); $section->blog_entries = Model_Blog_Entry::factory()->find_new(10); Widget::add('footer', $section); // Open Graph $og = array(); foreach ((array) Anqh::open_graph() as $key => $value) { $og[] = '<meta property="' . $key . '" content="' . HTML::chars($value) . '" />'; } if (!empty($og)) { Widget::add('head', implode("\n", $og)); } // Analytics if ($google_analytics = Kohana::$config->load('site.google_analytics')) { Widget::add('head', HTML::script_source("\nvar tracker;\nhead.js(\n\t{ 'google-analytics': 'http://www.google-analytics.com/ga.js' },\n\tfunction() {\n\t\ttracker = _gat._getTracker('" . $google_analytics . "');\n\t\ttracker._trackPageview();\n\t}\n);\n")); } // Ads /* $ads = Kohana::$config->load('site.ads'); if ($ads && $ads['enabled']) { foreach ($ads['slots'] as $ad => $slot) { if ($slot == 'side') { $this->view->add(View_Page::COLUMN_SIDE, View::factory('ads/' . $ad)); } else { Widget::add($slot, View::factory('ads/' . $ad), Widget::MIDDLE); } } }*/ // Do some CSS magic to page class $page_class = array_merge(array($this->language, $this->request->action(), self::$user ? 'authenticated' : 'unauthenticated'), explode(' ', $this->page_class)); $page_class = implode(' ', array_unique($page_class)); // Set the generic page variables $this->view->styles = $styles; $this->view->skins = $skins; $this->view->language = $this->language; $this->view->id = $this->page_id; $this->view->class = $page_class; if ($this->page_actions) { $this->view->tabs = $this->page_actions; } if ($this->page_breadcrumbs) { $this->view->breadcrumbs = $this->page_breadcrumbs; } // And finally the profiler stats if (self::$user && self::$user->has_role('admin')) { //in_array(Kohana::$environment, array(Kohana::DEVELOPMENT, Kohana::TESTING))) { Widget::add('foot', View::factory('generic/debug')); Widget::add('foot', View::factory('profiler/stats')); } } } parent::after(); }