/// <summary> /// Returns the file with all header/footers resolved as XML for further processing /// </summary> /// <param name="arguments"></param> /// <param name="templateFileContainer"></param> /// <param name="webConnection"></param> /// <param name="templateParsingState"></param> /// <returns></returns> private void ResolveHeaderFooter( IWebConnection webConnection, IDictionary<string, object> arguments, IFileContainer templateFileContainer, TemplateParsingState templateParsingState) { HashSet<string> checkedHeaderFooters = new HashSet<string>(); XmlDocument templateDocument = templateParsingState.LoadXmlDocumentAndReplaceGetParameters(arguments, templateFileContainer, XmlParseMode.Xml); // I think this is to work around an issue when directly viewing a template with an empty <oc:component /> tag templateParsingState.TemplateDocument = templateDocument; // While the first node isn't HTML, keep loading header/footers while ("html" != templateDocument.FirstChild.LocalName) { XmlNode firstChild = templateDocument.FirstChild; string headerFooter = "/DefaultTemplate/headerfooter.ochf"; XmlNodeList nodesToInsert; if (("componentdef" == firstChild.LocalName) && (templateParsingState.TemplateHandlerLocator.TemplatingConstants.TemplateNamespace == firstChild.NamespaceURI)) { XmlAttribute headerFooterAttribue = firstChild.Attributes["headerfooter"]; if (null != headerFooterAttribue) headerFooter = FileHandlerFactoryLocator.FileSystemResolver.GetAbsolutePath( templateFileContainer.ParentDirectoryHandler.FileContainer.FullPath, headerFooterAttribue.Value); nodesToInsert = firstChild.ChildNodes; } else nodesToInsert = templateDocument.ChildNodes; string headerFooterOverride; if (webConnection.GetParameters.TryGetValue("HeaderFooterOverride", out headerFooterOverride)) headerFooter = headerFooterOverride; if (checkedHeaderFooters.Contains(headerFooter)) throw new TemplateException("Looping within templates: " + headerFooter + " eventually points to itself as a headerfooter!!!"); else checkedHeaderFooters.Add(headerFooter); templateParsingState.SetCWD(nodesToInsert, templateFileContainer.ParentDirectoryHandler.FileContainer.FullPath); try { templateFileContainer = FileHandlerFactoryLocator.FileSystemResolver.ResolveFile(headerFooter); } catch (FileDoesNotExist fdne) { log.Error(headerFooter + " does not exist", fdne); throw new WebResultsOverrideException(WebResults.From(Status._500_Internal_Server_Error, headerFooter + " does not exist")); } templateDocument = templateParsingState.LoadXmlDocumentAndReplaceGetParameters( arguments, templateFileContainer, XmlParseMode.Xml); templateParsingState.TemplateDocument = templateDocument; // find <oc:component /> tag int numOcComponentTags = 0; XmlNodeList componentTags = templateDocument.GetElementsByTagName("component", templateParsingState.TemplateHandlerLocator.TemplatingConstants.TemplateNamespace); foreach (XmlNode componentNode in Enumerable<XmlNode>.FastCopy(Enumerable<XmlNode>.Cast(componentTags))) if ((null == componentNode.Attributes.GetNamedItem("url", templateParsingState.TemplateHandlerLocator.TemplatingConstants.TemplateNamespace)) && (null == componentNode.Attributes.GetNamedItem("src", templateParsingState.TemplateHandlerLocator.TemplatingConstants.TemplateNamespace))) { numOcComponentTags++; if (1 == numOcComponentTags) templateParsingState.ReplaceNodes(componentNode, nodesToInsert); else templateParsingState.ReplaceNodes( componentNode, templateParsingState.GenerateWarningNode("Warning: Duplicate <oc:component /> tag, count " + numOcComponentTags.ToString())); } // Attempt to recover from a missing <oc:component /> tag if (0 == numOcComponentTags) { XmlNodeList bodyTags = templateDocument.GetElementsByTagName( "body", templateParsingState.TemplateHandlerLocator.TemplatingConstants.HtmlNamespace); XmlElement bodyTag = null; if (null != bodyTags) if (bodyTags.Count > 0) bodyTag = (XmlElement)bodyTags[0]; if (null == bodyTag) { bodyTag = (XmlElement)templateDocument.FirstChild; } bodyTag.AppendChild( templateParsingState.GenerateWarningNode( @"WARNING!!! -------------- " + headerFooter + @" is missing a needed <oc:component /> tag!!! The tag must be empty with no attributes. This is where the content for each page is displayed")); XmlElement componentNode = templateDocument.CreateElement( "component", templateParsingState.TemplateHandlerLocator.TemplatingConstants.TemplateNamespace); bodyTag.AppendChild(componentNode); templateParsingState.ReplaceNodes(componentNode, nodesToInsert); } } templateParsingState.SetCWD(templateDocument.ChildNodes, templateFileContainer.ParentDirectoryHandler.FileContainer.FullPath); }
private static void ResolveDocument(IDictionary<string, object> arguments, XmlDocument templateDocument, TemplateParsingState templateParsingState) { templateParsingState.OnDocumentLoaded(arguments, templateDocument.FirstChild as XmlElement); bool continueResolving; XmlNodeChangedEventHandler documentChanged = delegate(object sender, XmlNodeChangedEventArgs e) { continueResolving = true; }; templateDocument.NodeChanged += documentChanged; templateDocument.NodeInserted += documentChanged; templateDocument.NodeRemoved += documentChanged; // Keep resolving oc:if, oc:component, oc:script, and oc:css tags while they're loaded int loopsLeft = 20; do { int innerLoopsLeft = 20; do { continueResolving = false; foreach (XmlElement element in templateParsingState.IterateNonDeferredElements(templateDocument)) try { templateParsingState.OnProcessElementForConditionalsAndComponents(arguments, element); } catch (Exception e) { log.Error("An error occured while processing " + element.OuterXml, e); templateParsingState.ReplaceNodes( element, templateParsingState.GenerateWarningNode("An error occured processing " + element.OuterXml)); } innerLoopsLeft--; } while (continueResolving && (innerLoopsLeft > 0)); foreach (XmlElement element in templateParsingState.IterateNonDeferredElements(templateDocument)) try { templateParsingState.OnProcessElementForDependanciesAndTemplates(arguments, element); } catch (Exception e) { log.Error("An error occured while processing " + element.OuterXml, e); templateParsingState.ReplaceNodes( element, templateParsingState.GenerateWarningNode("An error occured processing " + element.OuterXml)); } loopsLeft--; } while (continueResolving && (loopsLeft > 0)); templateDocument.NodeChanged -= documentChanged; templateDocument.NodeInserted -= documentChanged; templateDocument.NodeRemoved -= documentChanged; }