Detailed Explanation of Class for Dynamic Generation of Static Pages by C

  • 2021-09-12 01:56:33
  • OfStack

In this paper, an example is given to describe the class of C # to dynamically generate static pages. Share it for your reference, as follows:

Generating static pages dynamically has many advantages, such as generating html pages to be included by search engines. At the same time, it reduces the data access, reduces the pressure of database access, and improves the speed of web page opening.

Basic ideas:

Use a string as the page template, and then the page contains several flags (represented by {flag name}). When generating the page, replace the flags with corresponding values.

Implementation method:

When initializing the TextTemplate instance, read in the template, and divide the template into several parts with the mark as the dividing point. When generating the page, you only need to simply connect the template content with the mark value. For example:
Suppose you have a template ABCD {TAG1} EFG {TAG2} HIJ {TAG3} KMUN
During initialization, the template is divided into four strings: "ABCD", "EFG", "HIJ" and "KMUN".
Suppose TAG1= "123", TAG2= "456", TAG3= "789"
The generation is equivalent to executing "ABCD" + "123" + "EFG" + "456" + "HIJ" + "789" + "KMUN"

Code:


using System;
using System.Collections.Generic;
using System.Text;
using System.Text.RegularExpressions;
using System.Collections;
using System.IO;
/// <summary>
///  Denote 1 Text templates, which use the 1 String as a template, by replacing the flag in the template with the corresponding value (the flag in the template uses the  { Flag name }  Represents) generates new text 
/// </summary>
/// <example> The following code is generated with a text template IMG Sign 
/// <code>
/// static class Program
/// {
///  [STAThread]
///  static void Main()
///  {
///   TextTemplate temp = new TextTemplate("&lt;img src='{src}' alt='{alt}' /&gt;");
///   Console.WriteLine(temp.Render("pic.bmp","Image"));
///   Hashtable values = new Hashtable();
///   values.Add("src", "pic.bmp");
///   values.Add("alt", "image");
///   Console.WriteLine(temp.Render(values));
///  }
/// }
///
///  The output is: 
/// &lt;img src='pic.bmp' alt='Image' /&gt;
/// &lt;img src='pic.bmp' alt='image' /&gt;
///
/// </code>
/// </example>
public class TextTemplate
{
 TextTemplateTag[] _tags;
 String[] _contentParts;
 int _tagCount;
 private TextTemplate()
 {
  _tagCount = 0;
  _tags = null;
  _contentParts = null;
 }
 /// <summary>
 ///  Class with the specified template TextTemplate
 /// </summary>
 /// <param name="content"> Template content </param>
 public TextTemplate(String content)
 {
  FromString(content);
 }
 /// <summary>
 ///  Class with the specified template TextTemplate, Template content heavy file reading 
 /// </summary>
 /// <param name="file"> Template file location </param>
 /// <param name="encoding"> The encoding used by the file </param>
 public TextTemplate(string file, Encoding encoding)
 {
  StreamReader sr = new StreamReader(file, encoding);
  try
  {
   string content = sr.ReadToEnd();
   FromString(content);
  }
  catch (Exception)
  {
   sr.Close();
   throw;
  }
  sr.Close();
 }
 /// <summary>
 ///  Read the template and divide the template with the flag as the dividing point 
 /// </summary>
 /// <param name="content"></param>
 private void FromString(String content)
 {
  MatchCollection mc = Regex.Matches(content, "{\\w+}");
  _tagCount = mc.Count;
  _tags = new TextTemplateTag[mc.Count];
  _contentParts = new string[mc.Count + 1];
  int index = 0;
  foreach (Match m in mc)
  {
   _tags[index++] = new TextTemplateTag(m.Value.Substring(1, m.Value.Length - 2), m.Index, m.Length);
  }
  int start = 0;
  index = 0;
  foreach (TextTemplateTag con in _tags)
  {
   _contentParts[index] = content.Substring(start, con.Position - start);
   start = con.Position + con.Length;
   index++;
  }
  if (start < content.Length) _contentParts[index] = content.Substring(start);
 }
 /// <summary>
 ///  Generates text with the specified value 
 /// </summary>
 /// <param name="values"> The value corresponding to each flag (using the flag name as the key ) </param>
 /// <returns> Generated text </returns>
 /// <example> The following code is generated with a text template IMG Sign 
 /// <code>
 /// static class Program
 /// {
 ///  [STAThread]
 ///  static void Main()
 ///  {
 ///   TextTemplate temp = new TextTemplate("&lt;img src='{src}' alt='{alt}' /&gt;");
 ///   Console.WriteLine(temp.Render("pic.bmp","Image"));
 ///   Hashtable values = new Hashtable();
 ///   values.Add("src", "pic.bmp");
 ///   values.Add("alt", "image");
 ///   Console.WriteLine(temp.Render(values));
 ///  }
 /// }
 ///
 ///  The output is: 
 /// &lt;img src='pic.bmp' alt='Image' /&gt;
 /// &lt;img src='pic.bmp' alt='image' /&gt;
 ///
 /// </code>
 /// </example>
 public string Render(Hashtable values)
 {
  StringBuilder result = new StringBuilder(8 * 1024);
  int i = 0;
  for (i = 0; i < _tagCount; i++)
  {
   result.Append(_contentParts[i]);
   if (values[_tags[i].Name] != null)
    result.Append(values[_tags[i].Name]);
   else
    result.Append("{" + _tags[i].Name + "}");
  }
  result.Append(_contentParts[i]);
  return result.ToString();
 }
 /// <summary>
 ///  Generates text with the specified value 
 /// </summary>
 /// <param name="args"> The corresponding value of each flag ( Ignore the flag name, the 1 The flags correspond to the number 1 Parameters, and so on )</param>
 /// <returns> Generated text </returns>
 /// <example> The following code is generated with a text template IMG Sign 
 /// <code>
 /// static class Program
 /// {
 ///  [STAThread]
 ///  static void Main()
 ///  {
 ///   TextTemplate temp = new TextTemplate("&lt;img src='{src}' alt='{alt}' /&gt;");
 ///   Console.WriteLine(temp.Render("pic.bmp","Image"));
 ///   Hashtable values = new Hashtable();
 ///   values.Add("src", "pic.bmp");
 ///   values.Add("alt", "image");
 ///   Console.WriteLine(temp.Render(values));
 ///  }
 /// }
 ///
 ///  The output is: 
 /// &lt;img src='pic.bmp' alt='Image' /&gt;
 /// &lt;img src='pic.bmp' alt='image' /&gt;
 ///
 /// </code>
 /// </example>
 public string Render(params object[] args)
 {
  StringBuilder result = new StringBuilder(2 * 1024);
  int i = 0;
  for (i = 0; i < _tagCount; i++)
  {
   result.Append(_contentParts[i]);
   result.Append(args[i].ToString());
  }
  result.Append(_contentParts[i]);
  return result.ToString();
 }
 /// <summary>
 ///  Generates text with the specified value and saves it to a file 
 /// </summary>
 /// <param name="file"> Path to the file to save </param>
 /// <param name="encoding"> Coding of files </param>
 /// <param name="values"> The value corresponding to each flag (using the flag name as the key ) </param>
 public void SaveAs(string file, Encoding encoding, Hashtable values)
 {
  StreamWriter sw = new StreamWriter(file, false, encoding);
  try
  {
   String content = Render(values);
   sw.Write(content);
  }
  catch (Exception)
  {
   sw.Close();
   throw;
  }
  sw.Close();
 }
 /// <summary>
 ///  Generates text with the specified value and saves it to a file 
 /// </summary>
 /// <param name="file"> Path to the file to save </param>
 /// <param name="encoding"> Coding of files </param>
 /// <param name="args"> The corresponding value of each flag ( Ignore the flag name, the 1 The flags correspond to the number 1 Parameters, and so on )</param>
 public void SaveAs(string file, Encoding encoding, params object[] args)
 {
  StreamWriter sw = new StreamWriter(file, false, encoding);
  try
  {
   String content = Render(args);
   sw.Write(content);
  }
  catch (Exception)
  {
   sw.Close();
   throw;
  }
  sw.Close();
 }
 /// <summary>
 ///  Divides a template into small templates with a specified separator 
 /// </summary>
 /// <param name="splitTag"></param>
 /// <returns></returns>
 public TextTemplate[] Split(string splitTag)
 {
  List<TextTemplate> temps = new List<TextTemplate>();
  List<string> contentParts = new List<string>();
  List<TextTemplateTag> tags = new List<TextTemplateTag>();
  int i = 0;
  foreach (string content in _contentParts)
  {
   contentParts.Add(content);
   if (i >= _tags.Length || _tags[i].Name == splitTag)
   {
    TextTemplate newTemp = new TextTemplate();
    newTemp._contentParts = contentParts.ToArray();
    newTemp._tags = tags.ToArray();
    newTemp._tagCount = tags.Count;
    temps.Add(newTemp);
    contentParts.Clear();
    tags.Clear();
   }
   else
    tags.Add(new TextTemplateTag(_tags[i].Name, _tags[i].Position, _tags[i].Length));
   i++;
  }
  return temps.ToArray();
 }
}
internal class TextTemplateTag
{
 int _position, _length;
 string _name;
 public TextTemplateTag(string name, int pos, int len)
 {
  _name = name;
  _position = pos;
  _length = len;
 }
 public string Name
 {
  get { return _name; }
 }
 public int Position
 {
  get { return _position; }
 }
 public int Length
 {
  get { return _length; }
 }
}

Example code:


static class Program
{
 [STAThread]
 static void Main()
 {
  TextTemplate temp = new TextTemplate("<img src='{src}' alt='{alt}' />");
  Console.WriteLine(temp.Render("pic.bmp","Image"));
  Hashtable values = new Hashtable();
  values.Add("src", "pic.bmp");
  values.Add("alt", "image");
  Console.WriteLine(temp.Render(values));
 }
}

The output is:

< img src='pic.bmp' alt='Image' / >
< img src='pic.bmp' alt='image' / >

Other applications:

TextTemplate can also be used to generate an Web. Config file when installing a Web site by defining the following template:


<?xml version="1.0"?>
<configuration xmlns="http://schemas.microsoft.com/.NetConfiguration/v2.0">
 <appSettings></appSettings>
 <connectionStrings>
  <add
   name="DJDB.LocalSqlServer"
   connectionString="{CONNECTIONSTRING}"
   providerName="System.Data.SqlClient"
  />
 </connectionStrings>
  Other configurations 
</configuration>

Just set the value of the flag CONNECTIONSTRING, which is much more convenient than using the XMLDocument class.

Summary:

The advantages of TextTemplate are:

1. Templates are analyzed and stored separately only during initialization. When using the same template to generate multiple pages, it is only a simple connection between the contents of the template and the value of the logo, and it is not necessary to analyze the template every time. If Replace method of string is used, the string should be analyzed every time, and if the logo value contains the logo, it will affect the generated page.

2. Templates can be read from files, so template files can be edited by various web page making tools.

For more readers interested in C # related content, please check the topics on this site: "C # Data Structure and Algorithm Tutorial", "C # Common Control Usage Tutorial", "C # Object-Oriented Programming Introduction Tutorial" and "C # Programming Thread Use Skills Summary"

I hope this article is helpful to everyone's C # programming.


Related articles: