コード例 #1
0
ファイル: TemplateEngine.cs プロジェクト: GWBasic/ObjectCloud
        /// <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);
        }
コード例 #2
0
ファイル: TemplateEngine.cs プロジェクト: GWBasic/ObjectCloud
        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;
        }