/** * A recursive function that validates the project YAML based on the spec.yml * * @param BedrockNode The node to validate * @param string The name of the parent node */ protected function doValidation($setting, $parent_class = null) { foreach ($setting as $name => $result) { $value = $setting->get($name); $is_setting = $value instanceof BedrockNode; $class = $result->getBaseClass(); $validator = SilverSmithSpec::get($name); if (!$validator) { $validator = SilverSmithSpec::get($class); } if (!$validator) { $validator = SilverSmithSpec::get($class . ".AvailableNodes.{$name}"); } if (!$validator && $parent_class) { $validator = SilverSmithSpec::get($parent_class . ".AvailableNodes.{$name}"); } if (!$validator) { continue; } // If the setting came back as an object if ($is_setting) { // Check to make sure all nodes in the tree are allowed. if (!$validator->getUserDefined() && ($allowed_nodes = $validator->getAvailableNodes())) { $allowed = array_keys($allowed_nodes->toArray()); foreach ($value as $node => $config) { if (!in_array($node, $allowed)) { $this->errors[] = sprintf(_t('Bedrock.NODENOTALLOWED', 'The node %s is not allowed in %s'), $node, $name); } } } elseif ($validator->getUserDefined()) { foreach ($value as $node => $config) { if (class_exists("Bedrock" . $node)) { $this->errors[] = sprintf(_t('Bedrock.NODENOTALLOWED', 'The node %s is note allowed in %s'), $node, $name); } } } // Make sure any required nodes are present. if ($required = $validator->getRequiredNodes()) { if ($is_setting) { foreach ($required as $node) { if (!$value->get($node)) { $this->errors[] = sprintf(_t('Bedrock.NODEISREQUIRED', 'The node %s is required in %s'), $node, $name); } } } } } else { // Make sure it's not supposed to be an object if ($type = $validator->getDataType()) { if ($type == "setting") { $this->errors[] = sprintf(_t('Bedrock.MUSTBESETTING', 'The node "%s" should be a collection of nodes, not a plain value.'), $name); } else { $this->validateDataType($value, $type, $name); } } if ($vals = $validator->getPossibleValues()) { $this->validatePossibleValues($value, $vals, $name); } } if ($is_setting) { $this->doValidation($value, $result->getBaseClass()); } } }
/** * Displays the required spec for the SilverSmith project configuration file * * @see "silversmith help" * @param The parameters, e.g. from the command line */ public static function spec($params = array()) { self::load_interface_manifest(); say("PageTypes:"); say(" YourPageType:"); say(" Fields:"); say(" Tagline:"); say(""); $required = SilverSmithSpec::get("Field.RequiredNodes")->toArray(); foreach (SilverSmithSpec::get("Field.BaseNodes") as $key => $node) { $r = in_array($key, $required) ? ", required" : ""; $v = ""; if ($vals = $node->getPossibleValues()) { $v = " (" . implode(',', $vals) . ")"; } say(" ## {$node->getDescription()} [{$node->getDataType()}{$r}{$v}]"); say(" {$key}: {$node->getExample()}"); say(""); } say(" ## Components related to and managed in the context of this page"); say(" Components:"); say(" Testimonial:"); say(""); $required = SilverSmithSpec::get("Component.RequiredNodes"); if ($required) { $required = $required->toArray(); } foreach (SilverSmithSpec::get("Component.AvailableNodes") as $key => $node) { if (in_array($key, array('Fields', 'Components', 'Interface'))) { continue; } $r = in_array($key, $required) ? ", required" : ""; $v = ""; if ($vals = $node->getPossibleValues()) { $v = " (" . implode(',', $vals->toArray()) . ")"; } say(" ## {$node->getDescription()} [{$node->getDataType()}{$r}{$v}]"); say(" {$key}: {$node->getExample()}"); say(""); } say(" ## Define the interface used to manage this component in the context of the page"); say(" Interface:"); say(""); $required = SilverSmithSpec::get("Interface.RequiredNodes"); if ($required) { $required = $required->toArray(); } foreach (SilverSmithSpec::get("Interface.BaseNodes") as $key => $node) { $r = in_array($key, $required) ? ", required" : ""; $v = ""; if ($vals = $node->getPossibleValues()) { $v = " (" . implode(',', $vals->toArray()) . ")"; } say(" ## {$node->getDescription()} [{$node->getDataType()}{$r}{$v}]"); say(" {$key}: {$node->getExample()}"); say(""); } say(" ## Component fields can be defined in the same block as its parent page"); say(" Fields:"); say(" Author:"); say(""); $required = SilverSmithSpec::get("Field.RequiredNodes"); if ($required) { $required = $required->toArray(); } foreach (SilverSmithSpec::get("Field.BaseNodes") as $key => $node) { if (in_array($key, array('Tab', 'Before'))) { continue; } $r = in_array($key, $required) ? ", required" : ""; $v = ""; if ($vals = $node->getPossibleValues()) { $v = " (" . implode(',', $vals->toArray()) . ")"; } say(" ## {$node->getDescription()} [{$node->getDataType()}{$r}{$v}]"); say(" {$key}: {$node->getExample()}"); say(""); } $required = SilverSmithSpec::get("PageType.RequiredNodes"); if ($required) { $required = $required->toArray(); } else { $required = array(); } foreach (SilverSmithSpec::get("PageType.AvailableNodes") as $key => $node) { if (in_array($key, array('Fields', 'Components'))) { continue; } $r = in_array($key, $required) ? ", required" : ""; $v = ""; if ($vals = $node->getPossibleValues()) { $v = " (" . implode(',', $vals->toArray()) . ")"; } say(" ## {$node->getDescription()} [{$node->getDataType()}{$r}{$v}]"); say(" {$key}: {$node->getExample()}"); say(""); } say(" ## Standalone components that are not necessarily related to or managed on a specific page type."); say("Components:"); say(" Client:"); say(""); $required = SilverSmithSpec::get("Component.RequiredNodes"); if ($required) { $required = $required->toArray(); } foreach (SilverSmithSpec::get("Component.AvailableNodes") as $key => $node) { if (in_array($key, array('Fields', 'Components', 'Interface', 'Type', 'Tab'))) { continue; } $r = in_array($key, $required) ? ", required" : ""; $v = ""; if ($vals = $node->getPossibleValues()) { $v = " (" . implode(',', $vals->toArray()) . ")"; } say(" ## {$node->getDescription()} [{$node->getDataType()}{$r}{$v}]"); say(" {$key}: {$node->getExample()}"); say(""); } }