Hey Jeffrey,

2014-07-27 22:54 GMT+02:00 Jeffrey Scott Flesher Gmail <
jeffrey.scott.fles...@gmail.com>:

>  I have a temple like this:
>
> <?xml version="1.0" encoding="UTF-8" ?>
> <messages>
>     <message id="x-template">
>         <wt id='audio1' class='audio' type='audio/mpeg' width='640'
> height='360' src='/resources/audio.mp3'></wt>
>         ${audio1}
>         <wt id='audio2' class='audio' type='audio/mpeg' width='640'
> height='360' src='/resources/audio.mp3'></wt>
>         ${audio2}
>     </message>
> </messages>
>

You can do this if you change your template like this:

        ${widget:audio id='audio1' type='audio/mpeg' width='640'
height='360' src='/resources/audio.mp3'}
        ${widget:audio id='audio2' type='audio/mpeg' width='640'
height='360' src='/resources/audio.mp3'}

This would then use a 'widget' function that you add to the template, and
which is implemented below:

class WidgetFunction
{
public:
  typedef boost::function<Wt::WWidget *(const std::vector<Wt::WString>&)>
    InstatiateWidget;

  bool operator()(Wt::WTemplate *t, const std::vector<Wt::WString>& args,
  std::ostream& result);

  void registerType(const std::string& name, InstatiateWidget instatiate);

private:
  typedef std::map<std::string, InstatiateWidget> RegistryMap;
  RegistryMap registeredTypes_;

  static std::string getArg(const std::string& name,
    const std::vector<Wt::WString>& args);
};

bool WidgetFunction::operator()(Wt::WTemplate *t,
const std::vector<Wt::WString>& args,
std::ostream& result)
{
  std::string name = args[0].toUTF8();

  RegistryMap::const_iterator i = registeredTypes_.find(name);
  if (i == registeredTypes_.end()) {
    result << "?? WidgetFunction: no type registered: " << name << "??";
  } else {
    std::string id = getArg("id", args);

    Wt::WWidget *w = 0;
    if (!id.empty())
      w = t->resolveWidget(id);

    if (!w) {
      w = i->second(args);

      std::string cl = getArg("class", args);
      if (!cl.empty())
w->addStyleClass(cl);
    }

    if (!w) {
      result << "?? WidgetFunction: could not create instance of type "
     << name << "??";
    } else {
      if (id.empty())
id = w->id();
    }

    t->bindWidget(id, w);

    Wt::WString text = Wt::WString::fromUTF8("${" + id + "}");
    t->renderTemplateText(result, text);
  }

  return true;
}

void WidgetFunction::registerType(const std::string& name,
  InstatiateWidget instantiate)
{
  registeredTypes_[name] = instantiate;
}

std::string WidgetFunction::getArg(const std::string& name,
   const std::vector<Wt::WString>& args)
{
  for (unsigned i = 0; i < args.size(); ++i) {
    std::string s = args[i].toUTF8();
    if (boost::starts_with(s, name + "="))
      return s.substr(name.length()+1);
  }

  return std::string();
}

To register a new 'type', for example 'line-edit' you can then use:

Wt::WWidget *createLineEdit(const std::vector<Wt::WString>& args)
{
  return new Wt::WLineEdit(); // could also process the arguments...
}

WidgetFunction widgetFunction;
widgetFunction.registerType("line-edit", createLineEdit);

Using it, for example:

  Wt::WTemplate *t = new Wt::WTemplate("${widget:line-edit}");
  t->addFunction("widget", widgetFunction);

Regards,
koen
------------------------------------------------------------------------------
Want fast and easy access to all the code in your enterprise? Index and
search up to 200,000 lines of code with a free copy of Black Duck
Code Sight - the same software that powers the world's largest code
search on Ohloh, the Black Duck Open Hub! Try it now.
http://p.sf.net/sfu/bds
_______________________________________________
witty-interest mailing list
witty-interest@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/witty-interest

Reply via email to