2014-01-18 4 views
0

Я использую StringTemplate4, чтобы позволить пользователям передавать шаблон HTML и идентификатор страницы веб-службе, а затем получить результат анализа. Имя и количество полей являются динамическими, что означает, что, хотя некоторые страницы могут возвращать только одно значение для заданного поля, другие страницы могут возвращать многие. Примером является URL-адрес страницы. На каждой странице может быть несколько URL-адресов, но первое должно считаться URL-адресом по умолчанию (канонический URL-адрес). Я хочу, чтобы мои пользователи могли добавлять $url$ к шаблону, и он просто выплевывает первый URL-адрес. Я знаю, что StringTemplate не обеспечивает индексацию массивов, поэтому я не могу просто сказать $url[0]$, поэтому я принял другой подход. Вот мой код:StringTemplate C# переопределить поведение массива

public class TemplateField : Dictionary<string, dynamic> 
{ 
    // Empty class 
} 

public class TemplateValue : List<string> 
{ 
    public override string ToString(){ 
     return this.FirstOrDefault(); 
    } 
} 

// This is a test method to render a template using my planned objects 
public static string ReplaceTokens() 
{ 
    var template = @" 
     <Title>$Title$</Title> 
     <ul class=""menu""> 
      $menu:{m|<li><a href=""$m.url$"">$m.name$</a></li>};separator=""\n""$ 
     </ul>"; 

    var g = new TemplateGroup('$','$'); 
    var t = new Template(g,template); 

    var menu = new List<TemplateField>(); 

    var item1 = new TemplateField(); 
    item1.Add("name", new TemplateValue { "Home" }); 
    item1.Add("url", new TemplateValue { 
     "/home", 
     "/index", 
     "/default" 
    }); 
    t.Add("menu",item1); 

    var item2 = new TemplateField(); 
    item2.Add("name", new TemplateValue { "About Us" }); 
    item2.Add("url", new TemplateValue { "/about-us" }); 
    t.Add("menu", item2); 

    var item3 = new TemplateField(); 
    item3.Add("name", new TemplateValue { "Contact" }); 
    item3.Add("url", new TemplateValue { "/contact" }); 
    t.Add("menu", item3); 

    t.Add("Title", new TemplateValue { "My test" }); 
    return t.Render(); 
} 

Так как вы можете увидеть, посмотрев на моем шаблоне, я надеюсь, что $m.url$ сделает из «/ домов» вместо «/ дома/индекс/по умолчанию», как это делает в настоящее время , Я попытался выполнить это, переопределив метод ToString() в классе TemplateValue, но безрезультатно. Я попытался просмотреть источник для StringTemplate и не смог найти способ изменить значение, возвращаемое объектом при его рендеринге. Может кто-то указать мне верное направление?

+0

Я не знаком с StringTemplate, предполагая, что есть пользовательский форматирующий или форматирующий поставщик. Попробуйте найти что-то, что связано с 'IFormatProvider' или' ICustomFormatter'. –

ответ

1

Вы можете использовать $first(url)$. Если элемент не является массивом (или набором), то результатом этого выражения является только сам элемент.

0

В конце концов я перешел на XSLT. Я изначально избегал этого, потому что я не думал, что он достаточно изящный (например, с Razor). Но у него есть много плюсов, чтобы перевешивает, что один кон:

  • До тех пор, как я могу представить свой класс как XML, я могу иметь любой уровень сложности в объекте я передаю в шаблоне парсер.
  • Мне не нужны никакие пользовательские классы, такие как TemplateField и TemplateValue для представления моего объекта: простой XML будет делать.
  • Это стандартная технология, поэтому поддержка намного лучше, чем я могу ожидать от сторонних библиотек, а получение новых разработчиков до скорости будет намного проще.
  • Это позволяет мне использовать стандартную логику в шаблоне.
  • Это работает!
Смежные вопросы