Exemplo n.º 1
0
        //Constructor
        public Helper(string mailerDefPath, HttpContext ctx)
        {
            _ctx = ctx; //Current request context (needed because of the async nature of the processing)
            string props = IOHelper.ReadTextFromFile(mailerDefPath);

            //Get the Front Matter of the form action definition file
            _mailerProps = new SimpleYAMLParser(props);
            //Clone current request Form data
            CloneRequestData();
            //Add extra info to the managed data
            AddExtraInfoToRequestData();
        }
Exemplo n.º 2
0
        //Extracts Front-Matter from current file
        private void ProcessFrontMatter()
        {
            if (_FrontMatter != null)
            {
                return;
            }

            string strFM        = string.Empty;
            bool   cacheEnabled = Common.GetFieldValue("UseMDCaching", null, "1") == "1";

            if (cacheEnabled)                                               //If the file cache is enabled
            {
                strFM = HttpRuntime.Cache[this.FilePath + "_FM"] as string; //Try to read Front-Matter from cache
                if (!string.IsNullOrEmpty(strFM))                           //If it in the cache, use it
                {
                    _FrontMatter = new SimpleYAMLParser(strFM);
                    return;
                }
                else
                {
                    strFM = "---\r\n---";   //Re-set to an empty FrontMatter (if I use an empty string it would be reading contents from this for all the files without Front Matter
                }
            }

            //If cache is not enabled or the FM is not currently cached, read from contents
            //Default value (empty), prevents Content property from processing Front-Matter twice if it's still not read
            _FrontMatter = new SimpleYAMLParser(strFM);

            //Extract and remove YAML Front Matter
            EnsureContent();
            Match fm = FRONT_MATTER_RE.Match(this._content);

            if (fm.Length > 0) //If there's front matter available
            {
                strFM = fm.Groups[0].Value;
                //Save front matter text
                _FrontMatter = new SimpleYAMLParser(strFM);
            }

            //Cache FM contents if caching is enabled
            if (cacheEnabled)
            {
                HttpRuntime.Cache.Insert(this.FilePath + "_FM", strFM, new CacheDependency(this.FilePath)); //Add FM to cache with dependency on the current MD/MDH file
            }
        }
Exemplo n.º 3
0
        //Extracts Front-Matter from current file
        private void ProcessFrontMatter()
        {
            if (_FrontMatter != null)
            {
                return;
            }

            //Non empty value, for caching
            string strFM = "---\r\n---";

            strFM = GetFMFromCache();
            if (!string.IsNullOrEmpty(strFM)) //If it in the cache, just use it
            {
                _FrontMatter = new SimpleYAMLParser(strFM);
                return; //Ready!
            }
            else
            {
                //If cache is not enabled or the FM is not currently cached, read it from the file content
                //Default value (empty FM, but no empty string), prevents the Content property from processing Front-Matter twice if it's not read yet
                _FrontMatter = new SimpleYAMLParser(strFM);
            }


            //Extract and remove YAML Front Matter
            EnsureContent();

            //If it's a .yml file, wrap the full content as Front-Matter (.yml files don't neeed to have the FM delimiters, but I wan't to support them)
            if (this.FileExt == ".yml" && !_rawContent.StartsWith("---\r\n"))
            {
                _rawContent = "---\r\n" + _rawContent + "\r\n---";
            }

            strFM        = SimpleYAMLParser.GetFrontMatterFromContent(_rawContent);
            _FrontMatter = new SimpleYAMLParser(strFM);

            //Cache the final FM content (if caching is enabled)
            AddFMToCache(strFM);
        }
Exemplo n.º 4
0
 //Removes the front matter, if any, from the actual content of the file
 //and removes the extra empty lines at the beginning and the end
 private void RemoveFrontMatter()
 {
     _rawContent = SimpleYAMLParser.RemoveFrontMatterFromContent(_rawContent);
 }
Exemplo n.º 5
0
        /// <summary>
        /// Reads a template from cache if available. If not, reads it from disk.
        /// Substitutes the template fields such as {basefolder}, before caching the result
        /// </summary>
        /// <param name="filePath">Path to the template</param>
        /// <param name="ctx">The current request context (needed in in order to transform virtual paths)</param>
        /// <param name="isInclude">true to indicate that the current template is a fragment of other template, so that is excludes content and other fragments from processing</param>
        /// <returns>The text contents of the template</returns>
        /// <exception cref="System.Security.SecurityException">Thrown if the app has no read access to the requested file</exception>
        /// <exception cref="System.IO.FileNotFoundException">Thrown when the requested file does not exist</exception>
        private static string ReadTemplate(string templateVirtualPath, HttpContext ctx, List <string> cacheDependencies, List <string> graph = null, bool isInclude = false)
        {
            string templatePath  = ctx.Server.MapPath(templateVirtualPath);
            string cachedContent = HttpRuntime.Cache[templatePath] as string;   //Templates are always cached for performance reasons (no switch/parameter to disable it)

            if (string.IsNullOrEmpty(cachedContent))
            {
                //Check for circular references
                if (graph != null)
                {
                    //Check if current file is already on the graph
                    //if it is, then we have a circular reference
                    if (graph.Contains(templatePath))
                    {
                        throw new CircularReferenceException(String.Format("Template not valid!\nThe file '{0}' is a circular reference: {1}", templateVirtualPath, String.Join(" >\n ", graph.ToArray())));
                    }
                    graph.Add(templatePath);    //Add current include to the graph to track circular references
                }

                var templateContents = IOHelper.ReadTextFromFile(templatePath);  //Read template contents from disk

                //Add current file as cache dependency (the read process will add the fragments if needed)
                if (!cacheDependencies.Contains(templatePath))
                {
                    cacheDependencies.Add(templatePath);
                }

                string phValue;    //The value to substitute the placeholder

                /////////////////////////////////////////////
                // Process template inheritance (if any)
                /////////////////////////////////////////////

                //Check if there's Front-Matter or not
                string strFM = SimpleYAMLParser.GetFrontMatterFromContent(templateContents);
                //If FM is present
                if (strFM != SimpleYAMLParser.EMPTY_FRONT_MATTER)
                {
                    //Remove the FM
                    templateContents = SimpleYAMLParser.RemoveFrontMatterFromContent(templateContents);
                    //get the Layout field from the current template's FM
                    SimpleYAMLParser yaml   = new SimpleYAMLParser(strFM);
                    string           layout = yaml["layout"];
                    //If there's a layout specified, use it as the base layout for the current template
                    if (!string.IsNullOrEmpty(layout))
                    {
                        //Process the layout
                        string parentTemplateVPath   = VirtualPathUtility.RemoveTrailingSlash(VirtualPathUtility.GetDirectory(templateVirtualPath)) + "/" + layout;;
                        string parentTemplateContent = ReadTemplate(parentTemplateVPath, ctx, cacheDependencies, graph);
                        //Substitute the content field in the parent layout, with the current template's content
                        templateContents = TemplatingHelper.ReplacePlaceHolder(parentTemplateContent, "content", templateContents);
                    }
                }


                ////////////////////////////////////////////
                //Search for includes in the current file and substitute them, before substituting any other placeholder
                ////////////////////////////////////////////
                string[] includes = TemplatingHelper.GetAllPlaceHolderNames(templateContents, "", FILE_INCLUDES_PREFIX);

                //Substitute includes with their contents
                foreach (string include in includes)
                {
                    string includeFileName = VirtualPathUtility.RemoveTrailingSlash(VirtualPathUtility.GetDirectory(templateVirtualPath)) + "/" + include.Substring(FILE_INCLUDES_PREFIX.Length);  //The current template file folder + the include filename
                    try
                    {
                        //Initialize graph to detect circular references
                        List <string> newGraph;
                        if (graph == null)
                        {
                            newGraph = new List <string>()
                            {
                                templatePath
                            };
                        }
                        else
                        {
                            newGraph = graph;
                        }
                        phValue = ReadTemplate(includeFileName, ctx, cacheDependencies, newGraph, true);    //Insert the raw contents of the include (no processing!)
                    }
                    catch (CircularReferenceException crex)
                    {
                        throw crex;
                    }
                    catch   //If it fails, simply do nothing and show the error
                    {
                        phValue = String.Format("<!-- Include file '{0}' not found  -->", includeFileName);
                    }
                    templateContents = TemplatingHelper.ReplacePlaceHolder(templateContents, include, phValue);
                }


                if (!isInclude)
                {
                    //After inserting all the "includes", check if there's a content placeholder present (mandatory)
                    if (!TemplatingHelper.IsPlaceHolderPresent(templateContents, "content"))
                    {
                        throw new Exception("Invalid template '" + templateVirtualPath + "': The " + TemplatingHelper.GetPlaceholderName("content") + " placeholder must be present!");
                    }

                    //////////////////////////////
                    //Replace template-specific fields
                    //////////////////////////////
                    //Legacy "basefolder" placeholder (now "~/" it's recommended)
                    templateContents = TemplatingHelper.ReplacePlaceHolder(templateContents, "basefolder", "~/");
                    //Template base folder
                    templateContents = TemplatingHelper.ReplacePlaceHolder(templateContents, "templatebasefolder",
                                                                           VirtualPathUtility.RemoveTrailingSlash(VirtualPathUtility.GetDirectory(VirtualPathUtility.ToAbsolute(templateVirtualPath))));

                    //Transform virtual paths into absolute to the root paths (This is done only once per file if cached)
                    templateContents = WebHelper.TransformVirtualPaths(templateContents);

                    //If it's the main file, add result to cache with dependency on the file(s)
                    //Templates are cached ALWAYS, and this is not dependent on the caching parameter (that one is only for MarkDown or MDH files)
                    HttpRuntime.Cache.Insert(templatePath, templateContents, new CacheDependency(cacheDependencies.ToArray()));
                    //Keep a list of template's dependencies to reuse when not reading from cache
                    ctx.Application[templatePath] = cacheDependencies;
                }

                return(templateContents); //Return content
            }
            else
            {
                //Get dependencies for this template
                cacheDependencies.AddRange(ctx.Application[templatePath] as List <string>);
                return(cachedContent);   //Return directly from cache
            }
        }