2009-11-16 6 views
1

사이트의 템플릿이 html 파일에 정의 된 ASP.NET/C#에서 콘텐츠 관리 시스템을 작성하고 있습니다. 난 블록와 html 파일에 매개 변수를 전달하고 있습니다. 블록은 []으로 시작하고 으로 끝납니다.입니다. 몇 가지 간단한 블록이있는 템플릿의 예 :템플릿 구문 분석 및 반영

<html> 
<head> 
    <title>[Title]</title> 
    <meta name="description" content="[Description]" /> 
</head> 
<body> 
    <h1>[Headline]</h1> 
    <p>[Text]</p> 
</body> 
</html> 

이제 템플릿을 나타내는 클래스가 생겼습니다. 예제 템플릿 클래스는 다음과 같습니다

public class MyTemplate 
{ 
    public string Title 
    { 
     get; 
     set; 
    } 

    public string Description 
    { 
     get; 
     set; 
    } 

    public string Headline 
    { 
     get; 
     set;   
    } 

    public string Text 
    { 
     get; 
     set;   
    } 
} 

클래스 내가 쓰는 클래스, SQL하거나 모든 클래스에 Linq에 의해 생성 된 클래스를 수 있습니다.

블록을 속성 값으로 바꾸는 방법을 만들었습니다.

public static string ParseTemplateFromObject(string input, object obj) 
    { 
     return Regex.Replace(input, @"\[(.*?)\]", new MatchEvaluator(delegate(Match match) 
     { 
      var blockName = match.Result("$1"); 

      return obj.GetType().GetProperties().SingleOrDefault(p => p.Name.Equals(blockName, StringComparison.OrdinalIgnoreCase)) 
       .GetValue(obj, null).ToString(); 

     }), RegexOptions.Multiline); 
    } 

을 ... 그리고 노력 : 나는이 목적을 위해 정규 표현식을 사용하고 있습니다. 대문자와 소문자를 구별하기 위해 GetProperties()와 GetProperty 대신 Linq를 사용하고 있습니다. 그러나 이제 블록에서 매개 변수를 사용하려고 할 때 다른 문제가 생깁니다. 예 : 수직 메뉴를 만들고 싶습니다. 시스템의 메뉴는 수직 또는 수평이 될 수 있습니다

[Menu Id=1, Direction="Vertical"] 

그래서, 대신 재산의에서 값을 추출의 블록이 유형의 메소드를 호출하고 값의 추출 결정했다. 예 : 제대로 작동

public static string ParseTemplateFromObject(string input, object obj) 
    { 
     return Regex.Replace(input, @"\[(.*?)\]", new MatchEvaluator(delegate(Match match) 
     { 
      var blockName = match.Result("$1"); 

      var m = Regex.Match(blockName, "(?<Name>\\w+)=((?<Value>\\w+)|\"(?<Value>([^\"]*))\")"); 

      if (m.Captures.Count > 0) 
      { 
       var method = obj.GetType().GetMethods().Single(p => p.Name.Equals(blockName.Substring(0, blockName.IndexOf(' ')) 
        , StringComparison.OrdinalIgnoreCase)); 

       var methodParameters = method.GetParameters(); 
       var parameters = new object[methodParameters.Length]; 

       while (m.Success) 
       { 
        var name = m.Groups["Name"].Value; 
        var value = m.Groups["Value"].Value; 

        var methodParameter = methodParameters.Single(p => p.Name.ToLower() == name.ToLower()); 
        parameters[methodParameter.Position] = 
         Convert.ChangeType(value, methodParameter.ParameterType); 

        m = m.NextMatch(); 
       } 

       return method.Invoke(obj, parameters).ToString(); 
      } 
      else 
      { 
       return obj.GetType().GetProperties().SingleOrDefault(p => p.Name.Equals(blockName, StringComparison.OrdinalIgnoreCase)) 
        .GetValue(obj, null).ToString(); 

      } 
     }), RegexOptions.Multiline); 
    } 
} 

,하지만 난 그게 더 효과적으로 만들 수있는 방법을 찾고 있어요 :

public class MyTemplate 
{ 
    ... 
    public string Menu(int id, string direction) 
    { 
     string menu = ...; 
     return menu; 
    } 
} 

나는이 기능을 지원하는 내 ParseTemplateFromObject을 확장했다. 실제로 이것을 구현하는 것이 올바른 방법인지는 모르겠습니다.

감사합니다.

답변

0

코드 내에서 스타일을 지정하는 대신 실제 템플릿에서 토큰의 스타일링을 관리한다고 생각하십니까? 예를 들어 내 제안 된 접근 방식에 대한 이상적인 후보가 될 수있는 방향 속성이 있습니다. 그렇게하면 토큰 구문 분석을 매우 간단하게 유지할 수 있습니다.

1

아마도 ASP.Net에서 제공하는 기본 템플릿을 사용합니까? 즉, 표준 .aspx 페이지를 사용하여 템플릿을 정의한 다음 Server.Execute 메서드를 사용하여이 페이지에서 생성 된 출력을 캡처합니다. 서버 코드 블럭 (< % = %>)을 다음 중 하나에 사용할 수 있습니다. 1.) 코드 뒤에 노출 된 변수를 삽입하거나 2) 코드 배후에서 메소드를 실행합니다. 파싱 ​​코드를 업데이트하는 노력을 덜어 주며 널리 알려진 템플릿 형식을 제공합니다.

+0

콘솔 앱에서이 작업을 수행하려고하면 엉망이됩니다. – Shawn