public static function compile($source, $path, $todir, $importdirs) { // call Less to compile $parser = new lessc(); $parser->setImportDir(array_keys($importdirs)); $parser->setPreserveComments(true); $output = $parser->compile($source); // update url $arr = preg_split(T3Less::$rsplitbegin . T3Less::$kfilepath . T3Less::$rsplitend, $output, -1, PREG_SPLIT_DELIM_CAPTURE); $output = ''; $file = $relpath = ''; $isfile = false; foreach ($arr as $s) { if ($isfile) { $isfile = false; $file = $s; $relpath = T3Less::relativePath($todir, dirname($file)); $output .= "\n#" . T3Less::$kfilepath . "{content: \"{$file}\";}\n"; } else { $output .= ($file ? T3Path::updateUrl($s, $relpath) : $s) . "\n\n"; $isfile = true; } } return $output; }
public static function compile($source, $path, $todir, $importdirs) { $parser = new Less_Parser(); $parser->SetImportDirs($importdirs); $parser->parse($source, T3Less::relativePath($todir, dirname($path)) . basename($path)); $output = $parser->getCss(); return $output; }
public static function lesscall() { T3::import('core/less'); $result = array(); try { T3Less::compileAll(); $result['successful'] = JText::_('T3_MSG_COMPILE_SUCCESS'); } catch (Exception $e) { $result['error'] = JText::sprintf('T3_MSG_COMPILE_FAILURE', $e->getMessage()); } echo json_encode($result); }
public static function lesscall() { T3::import('core/less'); $input = JFactory::getApplication()->input; $result = array(); try { T3Less::compileAll($input->get('theme', '')); $result['successful'] = JText::_('T3_MSG_COMPILE_SUCCESS'); } catch (Exception $e) { $result['error'] = JText::sprintf('T3_MSG_COMPILE_FAILURE', $e->__toString()); } echo json_encode($result); }
/** * Update head - detect if devmode or themermode is enabled and less file existed, use less file instead of css * We also detect and update jQuery, Bootstrap to use T3 assets * * @return null */ function updateHead() { //state parameters $devmode = $this->getParam('devmode', 0); $themermode = $this->getParam('themermode', 1) && defined('T3_THEMER'); $theme = $this->getParam('theme', ''); $minify = $this->getParam('minify', 0); $minifyjs = $this->getParam('minify_js', 0); // detect RTL $doc = JFactory::getDocument(); $dir = $doc->direction; $is_rtl = $dir == 'rtl'; // As Joomla 3.0 bootstrap is buggy, we will not use it // We also prevent both Joomla bootstrap and T3 bootsrap are loaded // And upgrade jquery as our Framework require jquery 1.7+ if we are loading jquery from google $scripts = array(); if (version_compare(JVERSION, '3.0', 'ge')) { $t3bootstrap = false; $jabootstrap = false; foreach ($doc->_scripts as $url => $script) { if (strpos($url, T3_URL . '/bootstrap/js/bootstrap.js') !== false) { $t3bootstrap = true; if ($jabootstrap) { //we already have the Joomla bootstrap and we also replace to T3 bootstrap continue; } } if (preg_match('@media/jui/js/bootstrap(.min)?.js@', $url)) { if ($t3bootstrap) { //we have T3 bootstrap, no need to add Joomla bootstrap continue; } else { $scripts[T3_URL . '/bootstrap/js/bootstrap.js'] = $script; } $jabootstrap = true; } else { $scripts[$url] = $script; } } $doc->_scripts = $scripts; $scripts = array(); } // VIRTUE MART / JSHOPPING compatible foreach ($doc->_scripts as $url => $script) { $replace = false; if (strpos($url, '//ajax.googleapis.com/ajax/libs/jquery/') !== false && preg_match_all('@/jquery/(\\d+(\\.\\d+)*)?/@msU', $url, $jqver) || preg_match_all('@(^|\\/)jquery([-_]*(\\d+(\\.\\d+)+))?(\\.min)?\\.js@i', $url, $jqver)) { $idx = strpos($url, '//ajax.googleapis.com/ajax/libs/jquery/') !== false ? 1 : 3; if (is_array($jqver) && isset($jqver[$idx]) && isset($jqver[$idx][0])) { $jqver = explode('.', $jqver[$idx][0]); if (isset($jqver[0]) && (int) $jqver[0] <= 1 && isset($jqver[1]) && (int) $jqver[1] < 7) { $scripts[T3_URL . '/js/jquery-1.11.2' . ($devmode ? '' : '.min') . '.js'] = $script; $replace = true; } } } if (!$replace) { $scripts[$url] = $script; } } $doc->_scripts = $scripts; // end update javascript //Update css/less based on devmode and themermode $root = JURI::root(true); $current = JURI::current(); // $regex = '@' . preg_quote(T3_TEMPLATE_REL) . '/css/(rtl/)?(.*)\.css((\?|\#).*)?$@i'; $regex = '@' . preg_quote(T3_TEMPLATE_REL) . '/(.*)\\.css((\\?|\\#).*)?$@i'; $stylesheets = array(); foreach ($doc->_styleSheets as $url => $css) { // detect if this css in template css if (preg_match($regex, $url, $match)) { $fname = $match[1]; // remove rtl $fname = preg_replace('@(^|/)rtl/@mi', '\\1', $fname); // remove local $fname = preg_replace('@^local/@mi', '', $fname); // if (($devmode || $themermode) && is_file(T3_TEMPLATE_PATH . '/less/' . $fname . '.less')) { if ($devmode || $themermode) { // less file $lfname = preg_replace('@(^|/)css/@mi', '\\1less/', $fname); if (is_file(T3_TEMPLATE_PATH . '/' . $lfname . '.less')) { if ($themermode) { $newurl = T3_TEMPLATE_URL . '/' . $lfname . '.less'; $css['mime'] = 'text/less'; } else { T3::import('core/less'); $newurl = T3Less::buildCss(T3Path::cleanPath(T3_TEMPLATE_REL . '/' . $lfname . '.less'), true); } $stylesheets[$newurl] = $css; continue; } } $uri = null; // detect css available base on direction & theme if ($is_rtl && $theme) { // rtl css file $altfname = preg_replace('@(^|/)css/@mi', '\\1css/rtl/' . $theme . '/', $fname); $uri = T3Path::getUrl($altfname . '.css'); } if (!$uri && $is_rtl) { $altfname = preg_replace('@(^|/)css/@mi', '\\1css/rtl/', $fname); $uri = T3Path::getUrl($altfname . '.css'); } if (!$uri && $theme) { $altfname = preg_replace('@(^|/)css/@mi', '\\1css/themes/' . $theme . '/', $fname); $uri = T3Path::getUrl($altfname . '.css'); } if (!$uri) { $uri = T3Path::getUrl($fname . '.css'); } if ($uri) { $stylesheets[$uri] = $css; } continue; } $stylesheets[$url] = $css; } // update back $doc->_styleSheets = $stylesheets; //only check for minify if devmode is disabled if (!$devmode && ($minify || $minifyjs)) { T3::import('core/minify'); if ($minify) { T3Minify::optimizecss($this); } if ($minifyjs) { T3Minify::optimizejs($this); } } }
/** * * Clone Profile */ public static function duplicate($path) { $theme = JFactory::getApplication()->input->getCmd('theme'); $from = JFactory::getApplication()->input->getCmd('from'); $result = array(); if (empty($theme) || empty($from)) { return self::error(JText::_('T3_TM_INVALID_DATA_TO_SAVE')); } $source = $path . '/less/themes/' . $from; if (!JFolder::exists($source)) { return self::error(JText::sprintf('T3_TM_NOT_FOUND', $from)); } $dest = $path . '/less/themes/' . $theme; if (JFolder::exists($dest)) { return self::error(JText::sprintf('T3_TM_EXISTED', $theme)); } $result = array(); if (@JFolder::copy($source, $dest) == true) { $result['success'] = JText::_('T3_TM_CLONE_SUCCESSFULLY'); $result['theme'] = $theme; $result['reset'] = true; $result['type'] = 'duplicate'; } else { return self::error(JText::_('T3_TM_OPERATION_FAILED')); } //LessHelper::compileForTemplate(T3_TEMPLATE_PATH , $theme); T3::import('core/less'); T3Less::compileAll($theme); return self::response($result); }
public static function addStylesheet($lesspath) { // build less vars, once only static $vars_built = false; $t3less = T3Less::getInstance(); if (!$vars_built) { self::buildVars(); $vars_built = true; } $app = JFactory::getApplication(); $tpl = $app->getTemplate(true); $theme = $tpl->params->get('theme'); $doc = JFactory::getDocument(); if (defined('T3_THEMER')) { // in Themer mode, using js to parse less for faster $doc->addStylesheet(JURI::base(true) . '/' . T3Path::cleanPath($lesspath), 'text/less'); // Add lessjs to process lesscss $doc->addScript(T3_URL . '/js/less-1.3.3.js'); } else { // in development mode, using php to compile less for a better view of development if (preg_match('#(template(-responsive)?.less)#', $lesspath)) { // Development mode is on, try to include less file inside folder less/ // get the less content $lessContent = JFile::read(JPATH_ROOT . '/' . $lesspath); $path = dirname($lesspath); // parse less content if (preg_match_all('#^\\s*@import\\s+"([^"]*)"#im', $lessContent, $matches)) { foreach ($matches[1] as $url) { if ($url == 'vars.less') { continue; } $url = $path . '/' . $url; $cssurl = $t3less->buildCss(T3Path::cleanPath($url)); $doc->addStyleSheet($cssurl); } } } else { $cssurl = $t3less->buildCss(T3Path::cleanPath($lesspath)); $doc->addStyleSheet($cssurl); } // check and add theme less if ($theme && !preg_match('#bootstrap#', $lesspath)) { $themepath = str_replace('/less/', '/less/themes/' . $theme . '/', $lesspath); if (is_file(JPATH_ROOT . '/' . $themepath)) { $cssurl = $t3less->buildCss(T3Path::cleanPath($themepath)); $doc->addStyleSheet($cssurl); } } } }
/** * Add current template css base on template setting. * * @param $name String * file name, without .css * * @return string Block content */ function addCss($name, $addresponsive = true) { $devmode = $this->getParam('devmode', 0); $themermode = $this->getParam('themermode', 1); $responsive = $addresponsive ? $this->getParam('responsive', 1) : false; if (($devmode || $themermode && defined('T3_THEMER')) && ($url = T3Path::getUrl('less/' . $name . '.less', '', true))) { T3::import('core/less'); T3Less::addStylesheet($url); } else { $url = T3Path::getUrl('css/' . $name . '.css'); // Add this css into template if ($url) { $this->addStyleSheet($url); } } if ($responsive) { $this->addCss($name . '-responsive', false); } }
/** * @param string $path file path of less file to compile * @param string $topath file path of output css file * @return bool|mixed compile result or the css compiled content */ public static function compileCss($path, $topath = '', $split = false, $list = null) { $fromdir = dirname($path); $app = JFactory::getApplication(); $is_rtl = $app->getUserState('current_direction') == 'rtl'; if (empty($list)) { $list = self::parse($path); } if (empty($list)) { return false; } // join $list $content = ''; $importdirs = array(); $todir = $topath ? dirname($topath) : $fromdir; if (!is_dir(JPATH_ROOT . '/' . $todir)) { JFolder::create(JPATH_ROOT . '/' . $todir); } $importdirs[JPATH_ROOT . '/' . $fromdir] = './'; foreach ($list as $f => $import) { if ($import) { $importdirs[JPATH_ROOT . '/' . dirname($f)] = self::relativePath($fromdir, dirname($f)); $content .= "\n#" . self::$kfilepath . "{content: \"{$f}\";}\n"; // $content .= "@import \"$import\";\n\n"; if (is_file(JPATH_ROOT . '/' . $f)) { $less_content = file_get_contents(JPATH_ROOT . '/' . $f); // remove vars/mixins for template & t3 less if (preg_match('@' . preg_quote(T3_TEMPLATE_REL, '@') . '/@i', $f) || preg_match('@' . preg_quote(T3_REL, '@') . '/@i', $f)) { $less_content = preg_replace(self::$rimportvars, '', $less_content); } self::$_path = T3Path::relativePath($fromdir, dirname($f)) . '/'; $less_content = preg_replace_callback(self::$rimport, array('T3Less', 'cb_import_path'), $less_content); $content .= $less_content; } } else { $content .= "\n#" . self::$kfilepath . "{content: \"{$path}\";}\n"; $content .= $f . "\n\n"; } } // get vars $vars_files = explode('|', self::getVars('urls')); // build source $source = ''; // build import vars foreach ($vars_files as $var) { $var_file = T3Path::relativePath($fromdir, $var); $source .= "@import \"" . $var_file . "\";\n"; } // less content $source .= "\n#" . self::$kvarsep . "{content: \"separator\";}\n" . $content; // call Less to compile, // temporary compile into source path, then update url to destination later try { $output = T3LessCompiler::compile($source, $importdirs); } catch (Exception $e) { // echo 'Caught exception: ', $e->getMessage(), "\n"; throw new Exception($path . "<br />\n" . $e->getMessage()); } // process content //use cssjanus to transform the content if ($is_rtl) { $output = preg_split(self::$rsplitbegin . self::$krtlsep . self::$rsplitend, $output, -1, PREG_SPLIT_DELIM_CAPTURE); $rtlcontent = isset($output[2]) ? $output[2] : false; $output = $output[0]; T3::import('jacssjanus/ja.cssjanus'); $output = JACSSJanus::transform($output, true); // join with rtl content if ($rtlcontent) { $output = $output . "\n" . $rtlcontent; } } // skip duplicate clearfix $arr = preg_split(self::$rsplitbegin . self::$kvarsep . self::$rsplitend, $output, 2); if (preg_match('/bootstrap.less/', $path)) { $output = implode("\n", $arr); } else { $output = count($arr) > 1 ? $arr[1] : $arr[0]; } //remove comments and clean up $output = preg_replace(self::$rcomment, '', $output); $output = preg_replace(self::$rspace, "\n\n", $output); // update url for output $file_contents = self::updateUrl($output, $path, $todir, $split); // split if needed if ($split) { if (!empty($file_contents)) { //output the file to content and add to document foreach ($file_contents as $file => $content) { if ($file) { $content = trim($content); $filename = str_replace('/', '.', $file) . '.css'; JFile::write(JPATH_ROOT . '/' . $todir . '/' . $filename, $content); } } } } else { if ($topath) { JFile::write(JPATH_ROOT . '/' . $topath, $file_contents); } else { return $output; } } // write to path return true; }