/** * Compare the search and ignore props against the name. * Can use && or || in the comparison * @param {String} the type of the pattern that should be used in the view all * @param {String} the subtype of the pattern that be used in the view all * * @return {Array} the list of partials */ public function run($type = "", $subtype = "") { // default vars $patternPartials = array(); $styleGuideExcludes = Config::getOption("styleGuideExcludes"); $store = PatternData::get(); foreach ($store as $patternStoreKey => $patternStoreData) { if ($patternStoreData["category"] == "pattern" && !$patternStoreData["hidden"] && !$patternStoreData["noviewall"] && $patternStoreData["depth"] == 2 && !in_array($patternStoreData["type"], $styleGuideExcludes)) { if ($patternStoreData["type"] == $type && empty($subtype) || empty($type) && empty($subtype) || $patternStoreData["type"] == $type && $patternStoreData["subtype"] == $subtype) { $patternPartialData = array(); $patternPartialData["patternName"] = ucwords($patternStoreData["nameClean"]); $patternPartialData["patternLink"] = $patternStoreData["pathDash"] . "/" . $patternStoreData["pathDash"] . ".html"; $patternPartialData["patternPartial"] = $patternStoreData["partial"]; $patternPartialData["patternPartialCode"] = $patternStoreData["code"]; $patternPartialData["patternLineageExists"] = isset($patternStoreData["lineages"]); $patternPartialData["patternLineages"] = isset($patternStoreData["lineages"]) ? $patternStoreData["lineages"] : array(); $patternPartialData["patternLineageRExists"] = isset($patternStoreData["lineagesR"]); $patternPartialData["patternLineagesR"] = isset($patternStoreData["lineagesR"]) ? $patternStoreData["lineagesR"] : array(); $patternPartialData["patternLineageEExists"] = isset($patternStoreData["lineages"]) || isset($patternStoreData["lineagesR"]); $patternPartialData["patternDescExists"] = isset($patternStoreData["desc"]); $patternPartialData["patternDesc"] = isset($patternStoreData["desc"]) ? $patternStoreData["desc"] : ""; $patternPartialData["patternDescAdditions"] = isset($patternStoreData["partialViewDescAdditions"]) ? $patternStoreData["partialViewDescAdditions"] : array(); $patternPartialData["patternExampleAdditions"] = isset($patternStoreData["partialViewExampleAdditions"]) ? $patternStoreData["partialViewExampleAdditions"] : array(); //$patternPartialData["patternCSSExists"] = Config::$options["enableCSS"]; $patternPartialData["patternCSSExists"] = false; $patternPartials[] = $patternPartialData; } } } return array("partials" => $patternPartials, "cacheBuster" => Data::getOption("cacheBuster")); }
public function run($navItems) { // default vars $viewAllPaths = array(); $styleGuideExcludes = Config::getOption("styleGuideExcludes"); foreach ($navItems["patternTypes"] as $patternTypeKey => $patternTypeValues) { $patternType = $patternTypeValues["patternType"]; $patternTypeDash = $patternTypeValues["patternTypeDash"]; if (!in_array($patternType, $styleGuideExcludes)) { foreach ($patternTypeValues["patternTypeItems"] as $patternSubtypeKey => $patternSubtypeValues) { $patternSubtype = $patternSubtypeValues["patternSubtype"]; $patternSubtypeDash = $patternSubtypeValues["patternSubtypeDash"]; if (isset($patternSubtypeValues["patternSubtypeItems"])) { foreach ($patternSubtypeValues["patternSubtypeItems"] as $patternSubtypeItemKey => $patternSubtypeItemValues) { if (strpos($patternSubtypeItemValues["patternPartial"], "viewall-") !== false) { $viewAllPaths[$patternTypeDash][$patternSubtypeDash] = $patternType . "-" . $patternSubtype; } } } if (strpos($patternSubtypeItemValues["patternPartial"], "viewall-") !== false) { $viewAllPaths[$patternTypeDash]["all"] = $patternType; } } } } return $viewAllPaths; }
/** * Load a new Twig instance that is just a vanilla Twig rendering engine for strings */ public function __construct($options = array()) { // set-up the defaults $twigDebug = Config::getOption("twigDebug"); // set-up the loader list $loaders = array(); $filesystemLoaderPaths = array(); // see if source/_macros exists $macrosPath = Config::getOption("sourceDir") . DIRECTORY_SEPARATOR . "_macros"; if (is_dir($macrosPath)) { $filesystemLoaderPaths[] = $macrosPath; } // see if source/_layouts exists. if so add it to be searchable $layoutsPath = Config::getOption("sourceDir") . DIRECTORY_SEPARATOR . "_layouts"; if (is_dir($layoutsPath)) { $filesystemLoaderPaths[] = $layoutsPath; } // add the paths to the filesystem loader if the paths existed if (count($filesystemLoaderPaths) > 0) { $loaders[] = new \Twig_Loader_Filesystem($filesystemLoaderPaths); } $loaders[] = new \Twig_Loader_String(); // set-up Twig $twigLoader = new \Twig_Loader_Chain($loaders); $this->instance = new \Twig_Environment($twigLoader, array("debug" => $twigDebug)); // customize the loader $this->instance = TwigUtil::loadFilters($this->instance); $this->instance = TwigUtil::loadFunctions($this->instance); $this->instance = TwigUtil::loadTags($this->instance); $this->instance = TwigUtil::loadTests($this->instance); $this->instance = TwigUtil::loadDateFormats($this->instance); $this->instance = TwigUtil::loadDebug($this->instance); $this->instance = TwigUtil::loadMacros($this->instance); }
public function run() { if (version_compare(phpversion(), '5.4.0', '<')) { Console::writeWarning("you must have PHP 5.4.0 or greater to use this feature. you are using PHP " . phpversion() . "..."); } else { // set-up defaults $publicDir = Config::getOption("publicDir"); $coreDir = Config::getOption("coreDir"); $host = Console::findCommandOptionValue("host"); $host = $host ? $host : "localhost"; $port = Console::findCommandOptionValue("port"); $host = $port ? $host . ":" . $port : $host . ":8080"; $quiet = Console::findCommandOption("quiet"); // set-up the base command $command = $this->pathPHP . " -S " . $host . " " . $coreDir . "/server/router.php"; $commands = array(); $commands[] = array("command" => $command, "cwd" => $publicDir, "timeout" => null, "idle" => 1800); // get the watch command info if (Console::findCommandOption("with-watch")) { $watchCommand = new WatchCommand(); $commands[] = array("command" => $watchCommand->build() . " --no-procs", "timeout" => null, "idle" => 1800); } Console::writeInfo("server started on http://" . $host . " - use ctrl+c to exit..."); $processSpawner = new ProcessSpawner(); $processSpawner->spawn($commands, $quiet); } }
/** * Load listeners that may be a part of plug-ins that should be notified by the dispatcher */ protected static function loadListeners() { // default var $packagesDir = Config::getOption("packagesDir"); // see if the package dir exists. if it doesn't make it if (!is_dir($packagesDir)) { mkdir($packagesDir); } // make sure the listener data exists if (file_exists($packagesDir . "/listeners.json")) { // get listener list data $listenerList = json_decode(file_get_contents($packagesDir . "/listeners.json"), true); // get the listener info foreach ($listenerList["listeners"] as $listenerName) { if ($listenerName[0] != "_") { $listener = new $listenerName(); $listeners = $listener->getListeners(); foreach ($listeners as $event => $eventProps) { $eventPriority = isset($eventProps["priority"]) ? $eventProps["priority"] : 0; self::$instance->addListener($event, array($listener, $eventProps["callable"]), $eventPriority); } } } } }
/** * Set-up default vars */ public static function init() { // make sure config vars exist if (!Config::getOption("patternExtension")) { Console::writeError("the pattern extension config option needs to be set..."); } if (!Config::getOption("styleguideKit")) { Console::writeError("the styleguideKit config option needs to be set..."); } // set-up config vars $patternExtension = Config::getOption("patternExtension"); $pluginDir = Config::getOption("packagesDir"); $sourceDir = Config::getOption("sourceDir"); $styleguideKit = Config::getOption("styleguideKit"); // load pattern-lab's resources $partialPath = $pluginDir . "/" . $styleguideKit . "/views/partials"; self::$htmlHead = file_get_contents($partialPath . "/general-header." . $patternExtension); self::$htmlFoot = file_get_contents($partialPath . "/general-footer." . $patternExtension); // gather the user-defined header and footer information $patternHeadPath = $sourceDir . "/_meta/_00-head." . $patternExtension; $patternFootPath = $sourceDir . "/_meta/_01-foot." . $patternExtension; self::$patternHead = file_exists($patternHeadPath) ? file_get_contents($patternHeadPath) : ""; self::$patternFoot = file_exists($patternFootPath) ? file_get_contents($patternFootPath) : ""; // add the filesystemLoader $patternEngineBasePath = PatternEngine::getInstance()->getBasePath(); $filesystemLoaderClass = $patternEngineBasePath . "\\Loaders\\FilesystemLoader"; $options = array(); $options["templatePath"] = $pluginDir . "/" . $styleguideKit . "/views"; $options["partialsPath"] = $pluginDir . "/" . $styleguideKit . "/views/partials"; self::$filesystemLoader = new $filesystemLoaderClass($options); $stringLoaderClass = $patternEngineBasePath . "\\Loaders\\StringLoader"; self::$stringLoader = new $stringLoaderClass(); // i can't remember why i chose to implement the pattern loader directly in classes // i figure i had a good reason which is why it's not showing up here }
/** * Fetch a package from GitHub * @param {String} the command option to provide the rule for * @param {String} the path to the package to be downloaded * * @return {String} the modified file contents */ public function fetchStarterKit($starterkit = "") { // double-checks options was properly set if (empty($starterkit)) { Console::writeError("please provide a path for the starterkit before trying to fetch it..."); } // set default attributes $sourceDir = Config::getOption("sourceDir"); $tempDir = sys_get_temp_dir(); $tempDirSK = $tempDir . DIRECTORY_SEPARATOR . "pl-sk-archive"; $tempDirDist = $tempDirSK . DIRECTORY_SEPARATOR . "dist"; $tempComposerFile = $tempDirSK . DIRECTORY_SEPARATOR . "composer.json"; // figure out the options for the GH path list($org, $repo, $tag) = $this->getPackageInfo($starterkit); //get the path to the GH repo and validate it $tarballUrl = "https://github.com/" . $org . "/" . $repo . "/archive/" . $tag . ".tar.gz"; Console::writeInfo("downloading the starterkit..."); // try to download the given package if (!($package = @file_get_contents($tarballUrl))) { $error = error_get_last(); Console::writeError("the starterkit wasn't downloaded because:\n\n " . $error["message"]); } // write the package to the temp directory $tempFile = tempnam($tempDir, "pl-sk-archive.tar.gz"); file_put_contents($tempFile, $package); Console::writeInfo("finished downloading the starterkit..."); // make sure the temp dir exists before copying into it if (!is_dir($tempDirSK)) { mkdir($tempDirSK); } // extract, if the zip is supposed to be unpacked do that (e.g. stripdir) $zippy = Zippy::load(); $zippy->addStrategy(new UnpackFileStrategy()); $zippy->getAdapterFor('tar.gz')->open($tempFile)->extract($tempDirSK); // thrown an error if temp/dist/ doesn't exist if (!is_dir($tempDirDist)) { Console::writeError("the starterkit needs to contain a dist/ directory before it can be installed..."); } // check for composer.json. if it exists use it for determining things. otherwise just mirror dist/ to source/ if (file_exists($tempComposerFile)) { $tempComposerJSON = json_decode(file_get_contents($tempComposerFile), true); // see if it has a patternlab section that might define the files to move if (isset($tempComposerJSON["extra"]) && isset($tempComposerJSON["extra"]["patternlab"])) { Console::writeInfo("installing the starterkit..."); InstallerUtil::parseComposerExtraList($tempComposerJSON["extra"]["patternlab"], $starterkit, $tempDirDist); Console::writeInfo("installed the starterkit..."); } else { $this->mirrorDist($sourceDir, $tempDirDist); } } else { $this->mirrorDist($sourceDir, $tempDirDist); } // remove the temp files Console::writeInfo("cleaning up the temp files..."); $fs = new Filesystem(); $fs->remove($tempFile); $fs->remove($tempDir); Console::writeInfo("the starterkit installation is complete..."); return true; }
/** * Write out the time tracking file so the content sync service will work. A holdover * from how I put together the original AJAX polling set-up. */ public static function updateChangeTime() { if (is_dir(Config::getOption("publicDir"))) { file_put_contents(Config::getOption("publicDir") . "/latest-change.txt", time()); } else { Console::writeError("the public directory for Pattern Lab doesn't exist..."); } }
public function run() { if (Console::findCommandOption("list")) { // get all of the options $options = Config::getOptions(); // sort 'em alphabetically ksort($options); // find length of longest option $lengthLong = 0; foreach ($options as $optionName => $optionValue) { $lengthLong = strlen($optionName) > $lengthLong ? strlen($optionName) : $lengthLong; } // iterate over each option and spit it out foreach ($options as $optionName => $optionValue) { $optionValue = is_array($optionValue) ? implode(", ", $optionValue) : $optionValue; $optionValue = !$optionValue ? "false" : $optionValue; $spacer = Console::getSpacer($lengthLong, strlen($optionName)); Console::writeLine("<info>" . $optionName . ":</info>" . $spacer . $optionValue); } } else { if (Console::findCommandOption("get")) { // figure out which optino was passed $searchOption = Console::findCommandOptionValue("get"); $optionValue = Config::getOption($searchOption); // write it out if (!$optionValue) { Console::writeError("the --get value you provided, <info>" . $searchOption . "</info>, does not exists in the config..."); } else { $optionValue = is_array($optionValue) ? implode(", ", $optionValue) : $optionValue; $optionValue = !$optionValue ? "false" : $optionValue; Console::writeInfo($searchOption . ": <ok>" . $optionValue . "</ok>"); } } else { if (Console::findCommandOption("set")) { // find the value that was passed $updateOption = Console::findCommandOptionValue("set"); $updateOptionBits = explode("=", $updateOption); if (count($updateOptionBits) == 1) { Console::writeError("the --set value should look like <info>optionName=\"optionValue\"</info>. nothing was updated..."); } // set the name and value that were passed $updateName = $updateOptionBits[0]; $updateValue = $updateOptionBits[1][0] == "\"" || $updateOptionBits[1][0] == "'" ? substr($updateOptionBits[1], 1, strlen($updateOptionBits[1]) - 1) : $updateOptionBits[1]; // make sure the option being updated already exists $currentValue = Config::getOption($updateName); if (!$currentValue) { Console::writeError("the --set option you provided, <info>" . $updateName . "</info>, does not exists in the config. nothing will be updated..."); } else { Config::updateConfigOption($updateName, $updateValue); } } else { // no acceptable options were passed so write out the help Console::writeHelpCommand($this->command); } } } }
public function testGenerate() { Console::init(); Config::init(__DIR__ . "/../../../../../.."); Dispatcher::init(); $generator = new Generator(); $generator->generate(['foo' => 'baz']); echo ''; }
public function run() { // default vars $options = array(); $options["patternPaths"] = $this->patternPaths; $patternExtension = Config::getOption("patternExtension"); $patternSourceDir = Config::getOption("patternSourceDir"); $htmlHead = Template::getHTMLHead(); $htmlFoot = Template::getHTMLFoot(); $patternHead = Template::getPatternHead(); $patternFoot = Template::getPatternFoot(); $stringLoader = Template::getStringLoader(); // re-load the pattern data since we modified it $store = PatternData::get(); // load the pattern loader $patternEngineBasePath = PatternEngine::getInstance()->getBasePath(); $patternLoaderClass = $patternEngineBasePath . "\\Loaders\\PatternLoader"; $patternLoader = new $patternLoaderClass($options); // iterate to process each pattern FileChangeList::touchParentPatterns($store); foreach ($store as $patternStoreKey => $patternStoreData) { if ($patternStoreData["category"] == "pattern" && !$patternStoreData["hidden"]) { $fileName = FileChangeList::getFileNameByPatternData($patternStoreData); if (!Config::getOption("update") || FileChangeList::hasChanged($fileName)) { $data = Data::getPatternSpecificData($patternStoreKey); // add the pattern data so it can be exported $patternData = array(); //$patternFooterData["patternFooterData"]["cssEnabled"] = (Config::$options["enableCSS"] && isset($this->patternCSS[$p])) ? "true" : "false"; $patternData["cssEnabled"] = false; $patternData["lineage"] = isset($patternStoreData["lineages"]) ? $patternStoreData["lineages"] : array(); $patternData["lineageR"] = isset($patternStoreData["lineagesR"]) ? $patternStoreData["lineagesR"] : array(); $patternData["patternBreadcrumb"] = $patternStoreData["breadcrumb"]; $patternData["patternDesc"] = isset($patternStoreData["desc"]) ? $patternStoreData["desc"] : ""; $patternData["patternExtension"] = $patternExtension; $patternData["patternName"] = $patternStoreData["nameClean"]; $patternData["patternPartial"] = $patternStoreData["partial"]; $patternData["patternState"] = $patternStoreData["state"]; // extra copy for the code view $patternData["extraOutput"] = isset($patternStoreData["extraOutput"]) ? $patternStoreData["extraOutput"] : array(); // add the pattern lab specific mark-up // set a default var $exportClean = isset($options["exportClean"]) ? $options["exportClean"] : false; $data["patternLabHead"] = !$this->exportFiles ? $stringLoader->render(array("string" => $htmlHead, "data" => array("cacheBuster" => $data["cacheBuster"]))) : ""; $data["patternLabFoot"] = !$this->exportFiles ? $stringLoader->render(array("string" => $htmlFoot, "data" => array("cacheBuster" => $data["cacheBuster"], "patternData" => json_encode($patternData)))) : ""; if (isset($patternStoreData["patternRaw"])) { $header = !$this->exportClean ? $stringLoader->render(array("string" => $patternHead, "data" => $data)) : ""; $code = $patternLoader->render(array("pattern" => $patternStoreData["patternRaw"], "data" => $data)); $footer = !$this->exportClean ? $stringLoader->render(array("string" => $patternFoot, "data" => $data)) : ""; PatternData::setPatternOption($patternStoreKey, "header", $header); PatternData::setPatternOption($patternStoreKey, "code", $code); PatternData::setPatternOption($patternStoreKey, "footer", $footer); } } } } }
/** * Gather data from annotations.js and *.md files found in source/_annotations * * @return {Array} populates Annotations::$store */ public static function gather() { // set-up default var $annotationsDir = Config::getOption("annotationsDir"); // set-up the dispatcher $dispatcherInstance = Dispatcher::getInstance(); // dispatch that the data gather has started $dispatcherInstance->dispatch("annotations.gatherStart"); // set-up the comments store self::$store["comments"] = array(); // create the annotations dir if it doesn't exist if (!is_dir($annotationsDir)) { mkdir($annotationsDir); } // find the markdown-based annotations $finder = new Finder(); $finder->files()->name("*.md")->in($annotationsDir); $finder->sortByName(); foreach ($finder as $name => $file) { $data = array(); $data[0] = array(); $text = file_get_contents($file->getPathname()); $matches = strpos($text, PHP_EOL . "~*~" . PHP_EOL) !== false ? explode(PHP_EOL . "~*~" . PHP_EOL, $text) : array($text); foreach ($matches as $match) { list($yaml, $markdown) = Documentation::parse($match); if (isset($yaml["el"]) || isset($yaml["selector"])) { $data[0]["el"] = isset($yaml["el"]) ? $yaml["el"] : $yaml["selector"]; } else { $data[0]["el"] = "#someimpossibleselector"; } $data[0]["title"] = isset($yaml["title"]) ? $yaml["title"] : ""; $data[0]["comment"] = $markdown; self::$store["comments"] = array_merge(self::$store["comments"], $data); } } // read in the old style annotations.js, modify the data and generate JSON array to merge $data = array(); $oldStyleAnnotationsPath = $annotationsDir . DIRECTORY_SEPARATOR . "annotations.js"; if (file_exists($oldStyleAnnotationsPath)) { $text = trim(file_get_contents($oldStyleAnnotationsPath)); $text = str_replace("var comments = ", "", $text); if ($text[strlen($text) - 1] == ";") { $text = rtrim($text, ";"); } $data = json_decode($text, true); if ($jsonErrorMessage = JSON::hasError()) { JSON::lastErrorMsg(Console::getHumanReadablePath($oldStyleAnnotationsPath), $jsonErrorMessage, $data); } } // merge in any data from the old file if the json decode was successful if (is_array($data) && isset($data["comments"])) { self::$store["comments"] = array_merge(self::$store["comments"], $data["comments"]); } $dispatcherInstance->dispatch("annotations.gatherEnd"); }
public function __construct($options) { parent::__construct($options); $this->depthProp = 3; // 3 means that depth won't be checked $this->extProp = Config::getOption("patternExtension"); $this->isDirProp = false; $this->isFileProp = true; $this->searchProp = ""; $this->ignoreProp = ""; }
/** * Construct the sayings */ public function __construct() { // build the default sayings $sayings = array("have fun storming the castle", "be well, do good work, and keep in touch", "may the sun shine, all day long", "smile :)", "namaste", "walk as if you are kissing the earth with your feet", "to be beautiful means to be yourself", "i was thinking of the immortal words of socrates, who said '...i drank what?'", "let me take this moment to compliment you on your fashion sense, particularly your slippers", "42", "he who controls the spice controls the universe", "the greatest thing you'll ever learn is just to love and be loved in return", "nice wand", "i don't have time for a grudge match with every poseur in a parka", "han shot first", "what we've got here is a failure to communicate", "mama always said life was like a box of chocolates. you never know what you're gonna get", "soylent green is people", "a little word of advice, my friend. sometimes you gotta let those hard-to-reach chips go", "you don't understand! i coulda had class. i coulda been a contender. i could've been somebody, instead of a bum, which is what i am", "shop smart. shop s-mart", "i see dead people", "well, nobody's perfect", "it's alive! it's alive!", "you've got to ask yourself one question: 'do I feel lucky?' well, do ya, punk?", "badges? we ain't got no badges! we don't need no badges! i don't have to show you any stinking badges!", "the holy roman empire was neither holy nor roman. discuss.", "well, here's another nice mess you've gotten me into!", "here's johnny!", "hello, gorgeous", "nobody puts baby in a corner", "life moves pretty fast. if you don't stop and look around once in a while, you could miss it", "my precious", "be yourself; everyone else is already taken", "the ships hung in the sky in much the same way that bricks don't", "klaatu barada nikto", "i am putting myself to the fullest possible use, which is all i think that any conscious entity can ever hope to do", "just what do you think you're doing, dave?", "do what i do. hold tight and pretend it's a plan!", "(╯°□°)╯︵ ┻━┻", "¸.·´¯`·.´¯`·.¸¸.·´¯`·.¸><(((º>", "@}~}~~~", "(>'.')> (>'.')> (>'.')> ", "\\(^-^)/", "you've been at this awhile; perhaps it's time for a walk outside?"); // grab user sayings $userSayings = Config::getOption("sayings"); if (is_array($userSayings)) { $sayings = array_merge($sayings, $userSayings); } // i just didn't want to indent the crap above $this->sayings = $sayings; }
/** * Compare the search and ignore props against the name. * Can use && or || in the comparison * @param {String} the type of the pattern that should be used in the view all * @param {String} the subtype of the pattern that be used in the view all * * @return {Array} the list of partials */ public function run($type = "", $subtype = "") { // default vars $patternPartials = array(); $suffixRendered = Config::getOption("outputFileSuffixes.rendered"); foreach ($this->store as $patternStoreKey => $patternStoreData) { if ($patternStoreData["category"] == "pattern" && isset($patternStoreData["hidden"]) && !$patternStoreData["hidden"] && !$patternStoreData["noviewall"] && $patternStoreData["depth"] > 1 && !in_array($patternStoreData["type"], $this->styleGuideExcludes)) { if ($patternStoreData["type"] == $type && empty($subtype) || empty($type) && empty($subtype) || $patternStoreData["type"] == $type && $patternStoreData["subtype"] == $subtype) { $patternPartialData = array(); $patternPartialData["patternName"] = $patternStoreData["nameClean"]; $patternPartialData["patternLink"] = $patternStoreData["pathDash"] . "/" . $patternStoreData["pathDash"] . $suffixRendered . ".html"; $patternPartialData["patternPartial"] = $patternStoreData["partial"]; $patternPartialData["patternPartialCode"] = $patternStoreData["code"]; $patternPartialData["patternState"] = $patternStoreData["state"]; $patternPartialData["patternLineageExists"] = isset($patternStoreData["lineages"]); $patternPartialData["patternLineages"] = isset($patternStoreData["lineages"]) ? $patternStoreData["lineages"] : array(); $patternPartialData["patternLineageRExists"] = isset($patternStoreData["lineagesR"]); $patternPartialData["patternLineagesR"] = isset($patternStoreData["lineagesR"]) ? $patternStoreData["lineagesR"] : array(); $patternPartialData["patternLineageEExists"] = isset($patternStoreData["lineages"]) || isset($patternStoreData["lineagesR"]); $patternPartialData["patternDescExists"] = isset($patternStoreData["desc"]); $patternPartialData["patternDesc"] = isset($patternStoreData["desc"]) ? $patternStoreData["desc"] : ""; $patternPartialData["patternDescAdditions"] = isset($patternStoreData["partialViewDescAdditions"]) ? $patternStoreData["partialViewDescAdditions"] : array(); $patternPartialData["patternExampleAdditions"] = isset($patternStoreData["partialViewExampleAdditions"]) ? $patternStoreData["partialViewExampleAdditions"] : array(); // add the pattern data so it can be exported $patternData = array(); $patternData["lineage"] = isset($patternStoreData["lineages"]) ? $patternStoreData["lineages"] : array(); $patternData["lineageR"] = isset($patternStoreData["lineagesR"]) ? $patternStoreData["lineagesR"] : array(); $patternData["patternBreadcrumb"] = $patternStoreData["breadcrumb"]; $patternData["patternDesc"] = isset($patternStoreData["desc"]) ? $patternStoreData["desc"] : ""; $patternData["patternExtension"] = Config::getOption("patternExtension"); $patternData["patternName"] = $patternStoreData["nameClean"]; $patternData["patternPartial"] = $patternStoreData["partial"]; $patternData["patternState"] = $patternStoreData["state"]; $patternPartialData["patternData"] = json_encode($patternData); $patternPartials[] = $patternPartialData; } } else { if ($patternStoreData["category"] == "patternSubtype" && !in_array($patternStoreData["type"], $this->styleGuideExcludes)) { if ($patternStoreData["type"] == $type && empty($subtype) || empty($type) && empty($subtype) || $patternStoreData["type"] == $type && $patternStoreData["name"] == $subtype) { $patternPartialData = array(); $patternPartialData["patternName"] = $patternStoreData["nameClean"]; $patternPartialData["patternLink"] = $patternStoreData["pathDash"] . "/index.html"; $patternPartialData["patternPartial"] = $patternStoreData["partial"]; $patternPartialData["patternSectionSubtype"] = true; $patternPartialData["patternDesc"] = isset($patternStoreData["desc"]) ? $patternStoreData["desc"] : ""; $patternPartials[] = $patternPartialData; } } } } return array("partials" => $patternPartials, "cacheBuster" => $this->cacheBuster); }
public function run() { if (version_compare(phpversion(), '5.4.0', '<')) { Console::writeWarning("you must have PHP 5.4.0 or greater to use this feature. you are using PHP " . phpversion() . "..."); } else { // set-up defaults $publicDir = Config::getOption("publicDir"); $coreDir = Config::getOption("coreDir"); // start-up the server with the router Console::writeInfo("server started on localhost:8080. use ctrl+c to exit..."); passthru("cd " . $publicDir . " && " . $_SERVER["_"] . " -S localhost:8080 " . $coreDir . "/server/router.php"); } }
/** * Load a new Twig instance that uses the Pattern Loader */ public function __construct($options = array()) { // set-up default vars $twigDebug = Config::getOption("twigDebug"); $twigAutoescape = Config::getOption("twigAutoescape"); // set-up the loader list $loaders = array(); $filesystemLoaderPaths = array(); $loaders[] = new Twig_Loader_PatternPartialLoader(Config::getOption("patternSourceDir"), array("patternPaths" => $options["patternPaths"])); // see if source/_macros exists $macrosPath = Config::getOption("sourceDir") . DIRECTORY_SEPARATOR . "_macros"; if (is_dir($macrosPath)) { $filesystemLoaderPaths[] = $macrosPath; } // see if source/_layouts exists. if so add it to be searchable $layoutsPath = Config::getOption("sourceDir") . DIRECTORY_SEPARATOR . "_layouts"; if (is_dir($layoutsPath)) { $filesystemLoaderPaths[] = $layoutsPath; } // add source/_patterns subdirectories for Drupal theme template compatibility $patternSourceDir = Config::getOption("sourceDir") . DIRECTORY_SEPARATOR . "_patterns"; $patternObjects = new \RecursiveIteratorIterator(new \RecursiveDirectoryIterator($patternSourceDir), \RecursiveIteratorIterator::SELF_FIRST); $patternObjects->setFlags(\FilesystemIterator::SKIP_DOTS); // sort the returned objects $patternObjects = iterator_to_array($patternObjects); ksort($patternObjects); foreach ($patternObjects as $name => $object) { if ($object->isDir()) { $filesystemLoaderPaths[] = $object->getPathname(); } } // add the paths to the filesystem loader if the paths existed if (count($filesystemLoaderPaths) > 0) { $loaders[] = new \Twig_Loader_Filesystem($filesystemLoaderPaths); } $loaders[] = new \Twig_Loader_String(); // set-up Twig $twigLoader = new \Twig_Loader_Chain($loaders); $this->instance = new \Twig_Environment($twigLoader, array("debug" => $twigDebug, "autoescape" => $twigAutoescape)); // customize Twig $this->instance = TwigUtil::loadFilters($this->instance); $this->instance = TwigUtil::loadFunctions($this->instance); $this->instance = TwigUtil::loadTags($this->instance); $this->instance = TwigUtil::loadTests($this->instance); $this->instance = TwigUtil::loadDateFormats($this->instance); $this->instance = TwigUtil::loadDebug($this->instance); $this->instance = TwigUtil::loadMacros($this->instance); // add node visitor $this->instance->addNodeVisitor(new IncludeNodeVisitor()); }
/** * Gather data from annotations.js and *.md files found in source/_annotations * * @return {Array} populates Annotations::$store */ public static function gather() { // set-up default var $sourceDir = Config::getOption("sourceDir"); // set-up the dispatcher $dispatcherInstance = Dispatcher::getInstance(); // dispatch that the data gather has started $dispatcherInstance->dispatch("annotations.gatherStart"); // set-up the comments store self::$store["comments"] = array(); // iterate over all of the files in the annotations dir if (!is_dir($sourceDir . "/_annotations")) { Console::writeWarning("<path>_annotations/</path><warning> doesn't exist so you won't have annotations..."); mkdir($sourceDir . "/_annotations"); } // find the markdown-based annotations $finder = new Finder(); $finder->files()->name("*.md")->in($sourceDir . "/_annotations"); $finder->sortByName(); foreach ($finder as $name => $file) { $data = array(); $data[0] = array(); $text = file_get_contents($file->getPathname()); $matches = strpos($text, PHP_EOL . "~*~" . PHP_EOL) !== false ? explode(PHP_EOL . "~*~" . PHP_EOL, $text) : array($text); foreach ($matches as $match) { list($yaml, $markdown) = Documentation::parse($match); if (isset($yaml["el"]) || isset($yaml["selector"])) { $data[0]["el"] = isset($yaml["el"]) ? $yaml["el"] : $yaml["selector"]; } else { $data[0]["el"] = "#someimpossibleselector"; } $data[0]["title"] = isset($yaml["title"]) ? $yaml["title"] : ""; $data[0]["comment"] = $markdown; self::$store["comments"] = array_merge(self::$store["comments"], $data); } } // read in the old style annotations.js, modify the data and generate JSON array to merge if (file_exists($sourceDir . "/_annotations/annotations.js")) { $text = file_get_contents($sourceDir . "/_annotations/annotations.js"); $text = str_replace("var comments = ", "", $text); $text = rtrim($text, ";"); $data = json_decode($text, true); if ($jsonErrorMessage = JSON::hasError()) { JSON::lastErrorMsg("_annotations/annotations.js", $jsonErrorMessage, $data); } } // merge in any data from the old file self::$store["comments"] = array_merge(self::$store["comments"], $data["comments"]); $dispatcherInstance->dispatch("annotations.gatherEnd"); }
public function testIsUpdate() { Config::init(__DIR__ . "/../../../../../../", false); $sd = Config::getOption("patternSourceDir"); $fileName = $sd . "/00-atoms/_unused/banner.twig"; $patternStore = ['bla' => ['pathName' => "00-atoms/_unused/banner", 'ext' => 'twig']]; FileChangeList::init(Config::getOption("publicDir") . DIRECTORY_SEPARATOR . "fileChangeList.csv"); $this->assertTrue(touch($fileName, time() + 100)); FileChangeList::write(); touch($fileName, time()); clearstatcache(); FileChangeList::init(Config::getOption("publicDir") . DIRECTORY_SEPARATOR . "fileChangeList.csv"); $condition = FileChangeList::hasChanged($fileName); $this->assertTrue($condition); }
/** * Load all of the rules related to Pattern Engines. They're located in the plugin dir */ public static function loadRules() { // default var $configDir = Config::getOption("configDir"); // make sure the pattern engine data exists if (file_exists($configDir . "/patternengines.json")) { // get pattern engine list data $patternEngineList = json_decode(file_get_contents($configDir . "/patternengines.json"), true); // get the pattern engine info foreach ($patternEngineList["patternengines"] as $patternEngineName) { self::$rules[] = new $patternEngineName(); } } else { Console::writeError("The pattern engines list isn't available in <path>" . $configDir . "</path>..."); } }
public function run() { // find the value given to the command $init = Console::findCommandOption("i|init"); $starterkit = Console::findCommandOptionValue("f|install"); if ($init) { $patternEngine = Config::getOption("patternExtension"); $starterkit = "pattern-lab/starterkit-" . $patternEngine . "-base"; } if ($starterkit) { // download the starterkit $f = new Fetch(); $f->fetchStarterKit($starterkit); } else { Console::writeHelpCommand($this->command); } }
public function run($depth, $ext, $path, $pathName, $name) { // load default vars $patternType = PatternData::getPatternType(); $patternTypeDash = PatternData::getPatternTypeDash(); $dirSep = PatternData::getDirSep(); // make sure the pattern isn't hidden $hidden = $name[0] == "_"; // set-up the names, $name == 00-colors.md $doc = str_replace("." . $this->extProp, "", $name); // 00-colors $docDash = $this->getPatternName(str_replace("_", "", $doc), false); // colors $docPartial = $patternTypeDash . "-" . $docDash; // if the pattern isn't hidden do stuff if (!$hidden) { // default vars $patternSourceDir = Config::getOption("patternSourceDir"); // parse data $text = file_get_contents($patternSourceDir . "/" . $pathName); list($yaml, $markdown) = Documentation::parse($text); // grab the title and unset it from the yaml so it doesn't get duped in the meta if (isset($yaml["title"])) { $title = $yaml["title"]; unset($yaml["title"]); } // figure out if this is a pattern subtype $patternSubtypeDoc = false; if ($depth == 1) { // go through all of the directories to see if this one matches our doc foreach (glob($patternSourceDir . "/" . $patternType . "/*", GLOB_ONLYDIR) as $dir) { $dir = str_replace($patternSourceDir . "/" . $patternType . "/", "", $dir); if ($dir == $doc) { $patternSubtypeDoc = true; break; } } } $category = $patternSubtypeDoc ? "patternSubtype" : "pattern"; $patternStoreKey = $patternSubtypeDoc ? $docPartial . "-plsubtype" : $docPartial; $patternStoreData = array("category" => $category, "nameClean" => $title, "desc" => $markdown, "descExists" => true, "meta" => $yaml, "full" => $doc); // if the pattern data store already exists make sure this data overwrites it $patternStoreData = PatternData::checkOption($patternStoreKey) ? array_replace_recursive(PatternData::getOption($patternStoreKey), $patternStoreData) : $patternStoreData; PatternData::setOption($patternStoreKey, $patternStoreData); } }
/** * Compare the search and ignore props against the name. * Can use && or || in the comparison * @param {String} the type of the pattern that should be used in the view all * @param {String} the subtype of the pattern that be used in the view all * * @return {Array} the list of partials */ public function run($type = "", $subtype = "") { // default vars $patternPartials = array(); $styleGuideExcludes = Config::getOption("styleGuideExcludes"); $store = PatternData::get(); foreach ($store as $patternStoreKey => $patternStoreData) { if ($patternStoreData["category"] == "pattern" && !$patternStoreData["hidden"] && !$patternStoreData["noviewall"] && $patternStoreData["depth"] == 2 && !in_array($patternStoreData["type"], $styleGuideExcludes)) { if ($patternStoreData["type"] == $type && empty($subtype) || empty($type) && empty($subtype) || $patternStoreData["type"] == $type && $patternStoreData["subtype"] == $subtype) { $patternPartialData = array(); $patternPartialData["patternName"] = ucwords($patternStoreData["nameClean"]); $patternPartialData["patternLink"] = $patternStoreData["pathDash"] . "/" . $patternStoreData["pathDash"] . ".html"; $patternPartialData["patternPartial"] = $patternStoreData["partial"]; $patternPartialData["patternPartialCode"] = $patternStoreData["code"]; $patternPartialData["patternLineageExists"] = isset($patternStoreData["lineages"]); $patternPartialData["patternLineages"] = isset($patternStoreData["lineages"]) ? $patternStoreData["lineages"] : array(); $patternPartialData["patternLineageRExists"] = isset($patternStoreData["lineagesR"]); $patternPartialData["patternLineagesR"] = isset($patternStoreData["lineagesR"]) ? $patternStoreData["lineagesR"] : array(); $patternPartialData["patternLineageEExists"] = isset($patternStoreData["lineages"]) || isset($patternStoreData["lineagesR"]); $patternPartialData["patternDescExists"] = isset($patternStoreData["desc"]); $patternPartialData["patternDesc"] = isset($patternStoreData["desc"]) ? $patternStoreData["desc"] : ""; $patternPartialData["patternDescAdditions"] = isset($patternStoreData["partialViewDescAdditions"]) ? $patternStoreData["partialViewDescAdditions"] : array(); $patternPartialData["patternExampleAdditions"] = isset($patternStoreData["partialViewExampleAdditions"]) ? $patternStoreData["partialViewExampleAdditions"] : array(); //$patternPartialData["patternCSSExists"] = Config::$options["enableCSS"]; $patternPartialData["patternCSSExists"] = false; // add the pattern data so it can be exported $patternData = array(); //$patternFooterData["patternFooterData"]["cssEnabled"] = (Config::$options["enableCSS"] && isset($this->patternCSS[$p])) ? "true" : "false"; $patternData["cssEnabled"] = false; $patternData["lineage"] = isset($patternStoreData["lineages"]) ? $patternStoreData["lineages"] : array(); $patternData["lineageR"] = isset($patternStoreData["lineagesR"]) ? $patternStoreData["lineagesR"] : array(); $patternData["patternBreadcrumb"] = $patternStoreData["breadcrumb"]; $patternData["patternDesc"] = isset($patternStoreData["desc"]) ? $patternStoreData["desc"] : ""; $patternData["patternExtension"] = ".mustache"; $patternData["patternName"] = $patternStoreData["nameClean"]; $patternData["patternPartial"] = $patternStoreData["partial"]; $patternData["patternState"] = $patternStoreData["state"]; $patternPartialData["patternData"] = json_encode($patternData); $patternPartials[] = $patternPartialData; } } } return array("partials" => $patternPartials, "cacheBuster" => Data::getOption("cacheBuster")); }
/** * Load all of the rules related to Pattern Engines. They're located in the plugin dir */ public static function loadRules() { // default var $packagesDir = Config::getOption("packagesDir"); // see if the package dir exists. if it doesn't it means composer hasn't been run if (!is_dir($packagesDir)) { Console::writeError("you haven't fully set-up Pattern Lab yet. please add a pattern engine..."); } // make sure the pattern engine data exists if (file_exists($packagesDir . "/patternengines.json")) { // get pattern engine list data $patternEngineList = json_decode(file_get_contents($packagesDir . "/patternengines.json"), true); // get the pattern engine info foreach ($patternEngineList["patternengines"] as $patternEngineName) { self::$rules[] = new $patternEngineName(); } } else { Console::writeError("The pattern engines list isn't available in <path>" . $packagesDir . "</path>..."); } }
/** * Set-up default vars */ public static function init() { // make sure config vars exist if (!Config::getOption("patternExtension")) { Console::writeError("the pattern extension config option needs to be set..."); } if (!Config::getOption("styleguideKit")) { Console::writeError("the styleguideKit config option needs to be set..."); } // set-up config vars $patternExtension = Config::getOption("patternExtension"); $metaDir = Config::getOption("metaDir"); $styleguideKit = Config::getOption("styleguideKit"); $styleguideKitPath = Config::getOption("styleguideKitPath"); if (!$styleguideKitPath || !is_dir($styleguideKitPath)) { Console::writeError("your styleguide won't render because i can't find your styleguide files. are you sure they're at <path>" . Console::getHumanReadablePath($styleguideKitPath) . "</path>? you can fix this in <path>./config/config.yml</path> by editing styleguideKitPath..."); } // load pattern-lab's resources $partialPath = $styleguideKitPath . DIRECTORY_SEPARATOR . "views" . DIRECTORY_SEPARATOR . "partials"; $generalHeaderPath = $partialPath . DIRECTORY_SEPARATOR . "general-header." . $patternExtension; $generalFooterPath = $partialPath . DIRECTORY_SEPARATOR . "general-footer." . $patternExtension; self::$htmlHead = file_exists($generalHeaderPath) ? file_get_contents($generalHeaderPath) : ""; self::$htmlFoot = file_exists($generalFooterPath) ? file_get_contents($generalFooterPath) : ""; // gather the user-defined header and footer information $patternHeadPath = $metaDir . DIRECTORY_SEPARATOR . "_00-head." . $patternExtension; $patternFootPath = $metaDir . DIRECTORY_SEPARATOR . "_01-foot." . $patternExtension; self::$patternHead = file_exists($patternHeadPath) ? file_get_contents($patternHeadPath) : ""; self::$patternFoot = file_exists($patternFootPath) ? file_get_contents($patternFootPath) : ""; // add the filesystemLoader $patternEngineBasePath = PatternEngine::getInstance()->getBasePath(); $filesystemLoaderClass = $patternEngineBasePath . "\\Loaders\\FilesystemLoader"; $options = array(); $options["templatePath"] = $styleguideKitPath . DIRECTORY_SEPARATOR . "views"; $options["partialsPath"] = $options["templatePath"] . DIRECTORY_SEPARATOR . "partials"; self::$filesystemLoader = new $filesystemLoaderClass($options); $stringLoaderClass = $patternEngineBasePath . "\\Loaders\\StringLoader"; self::$stringLoader = new $stringLoaderClass(); // i can't remember why i chose to implement the pattern loader directly in classes // i figure i had a good reason which is why it's not showing up here }
public function run($depth, $ext, $path, $pathName, $name) { // load default vars $patternTypeDash = PatternData::getPatternTypeDash(); // should this pattern get rendered? $hidden = $name[0] == "_"; // set-up the names, $name == foo.json $pattern = str_replace("." . $ext, "", $name); // foo $patternDash = $this->getPatternName($pattern, false); // foo $patternPartial = $patternTypeDash . "-" . $patternDash; // atoms-foo if (!$hidden) { $patternStoreData = array("category" => "pattern"); $file = file_get_contents(Config::getOption("patternSourceDir") . "/" . $pathName); if ($ext == "json") { $data = json_decode($file, true); if ($jsonErrorMessage = JSON::hasError()) { JSON::lastErrorMsg($name, $jsonErrorMessage, $data); } } else { try { $data = YAML::parse($file); } catch (ParseException $e) { printf("unable to parse " . $pathNameClean . ": %s..\n", $e->getMessage()); } // single line of text won't throw a YAML error. returns as string if (gettype($data) == "string") { $data = array(); } } $patternStoreData["data"] = $data; // create a key for the data store $patternStoreKey = $patternPartial; // if the pattern data store already exists make sure it is merged and overwrites this data $patternStoreData = PatternData::checkOption($patternStoreKey) ? array_replace_recursive(PatternData::getOption($patternStoreKey), $patternStoreData) : $patternStoreData; PatternData::setOption($patternStoreKey, $patternStoreData); } }
public function run() { // load default vars $patternExtension = Config::getOption("patternExtension"); $patternSourceDir = Config::getOption("patternSourceDir"); // load the pattern data $store = PatternData::get(); // iterate to get raw data loaded into the PatternData Store foreach ($store as $patternStoreKey => $patternStoreData) { if ($patternStoreData["category"] == "pattern" && !$patternStoreData["hidden"]) { // figure out the source path for the pattern to render $srcPath = isset($patternStoreData["pseudo"]) ? PatternData::getPatternOption($patternStoreData["original"], "pathName") : $patternStoreData["pathName"]; // load the raw data so it can be modified/rendered $path = $patternSourceDir . "/" . $srcPath . "." . $patternExtension; if (file_exists($path)) { PatternData::setPatternOption($patternStoreKey, "patternRaw", file_get_contents($path)); } else { Console::writeError($patternStoreData["partial"] . " wasn't found for loading. the given path: " . $path); } } } }
protected function starterKitSuggestions() { Console::writeLine(""); $composerPath = Config::getOption("baseDir") . "/composer.json"; if (file_exists($composerPath)) { $json = file_get_contents($composerPath); $data = json_decode($json, true); if ($jsonErrorMessage = JSON::hasError()) { JSON::lastErrorMsg(Console::getHumanReadablePath($oldStyleAnnotationsPath), $jsonErrorMessage, $data); } if (isset($data["extra"]) && isset($data["extra"]["patternlab"]) && isset($data["extra"]["patternlab"]["starterKitSuggestions"])) { $starterKitSuggestions = $data["extra"]["patternlab"]["starterKitSuggestions"]; Console::writeInfo("suggested starterkits that work with this edition:", false, true); foreach ($starterKitSuggestions as $i => $suggestion) { $num = $i + 1; Console::writeLine($num . ": " . $suggestion, true); } // hack around installer util feature in Console::promptInput InstallerUtil::$isInteractive = true; // prompt for input on the suggestions Console::writeLine(""); $prompt = "choose an option or hit return to cancel:"; $options = "(ex. 1)"; $input = Console::promptInput($prompt, $options, "1"); $result = (int) $input - 1; if (isset($starterKitSuggestions[$result])) { Console::writeLine(""); $f = new Fetch(); $result = $f->fetchStarterKit($starterKitSuggestions[$result]); } } else { Console::writeWarning("this edition has no starterkits to suggested...", false, true); } } else { Console::writeError("can't find composer.json to get suggestions...", false, true); } }
/** * Move static files from source/ to public/ */ protected function moveStatic() { // set-up the dispatcher $dispatcherInstance = Dispatcher::getInstance(); // note the start of the operation $dispatcherInstance->dispatch("generator.moveStaticStart"); // common values $publicDir = Config::getOption("publicDir"); $sourceDir = Config::getOption("sourceDir"); $ignoreExt = Config::getOption("ie"); $ignoreDir = Config::getOption("id"); // iterate over all of the other files in the source directory $objects = new \RecursiveIteratorIterator(new \RecursiveDirectoryIterator($sourceDir), \RecursiveIteratorIterator::SELF_FIRST); // make sure dots are skipped $objects->setFlags(\FilesystemIterator::SKIP_DOTS); foreach ($objects as $name => $object) { // clean-up the file name and make sure it's not one of the pattern lab files or to be ignored $fileName = str_replace($sourceDir . DIRECTORY_SEPARATOR, "", $name); if ($fileName[0] != "_" && !in_array($object->getExtension(), $ignoreExt) && !in_array($object->getFilename(), $ignoreDir)) { // catch directories that have the ignored dir in their path $ignored = FileUtil::ignoreDir($fileName); // check to see if it's a new directory if (!$ignored && $object->isDir() && !is_dir($publicDir . "/" . $fileName)) { mkdir($publicDir . "/" . $fileName); } // check to see if it's a new file or a file that has changed if (!$ignored && $object->isFile() && !file_exists($publicDir . "/" . $fileName)) { FileUtil::moveStaticFile($fileName); } } } // note the end of the operation $dispatcherInstance->dispatch("generator.moveStaticEnd"); }
/** * Load functions for the Twig PatternEngine * @param {Instance} an instance of the twig engine * * @return {Instance} an instance of the twig engine */ public static function loadTests($instance) { // load defaults $testDir = Config::getOption("sourceDir") . DIRECTORY_SEPARATOR . "_twig-components/tests"; $testExt = Config::getOption("twigTestExt"); $testExt = $testExt ? $testExt : "test.php"; if (is_dir($testDir)) { // loop through the test dir... $finder = new Finder(); $finder->files()->name("*\\." . $testExt)->in($testDir); $finder->sortByName(); foreach ($finder as $file) { // see if the file should be ignored or not $baseName = $file->getBasename(); if ($baseName[0] != "_") { include $file->getPathname(); // $test should be defined in the included file if (isset($test)) { $instance->addTest($test); unset($test); } } } } return $instance; }