<html>
  <head>
    <meta content="text/html; charset=ISO-8859-1"
      http-equiv="Content-Type">
  </head>
  <body text="#000000" bgcolor="#FFFFFF">
    <div class="moz-cite-prefix">Le 15/05/2014 23:51, aurélien campéas a
      écrit :<br>
    </div>
    <blockquote
cite="mid:CAPfKyyqdpXzVcouxdisd=eoP+4XNXT8jo1Trmhehnmrs1Ab8ag@mail.gmail.com"
      type="cite">
      <div dir="ltr"><br>
        <div class="gmail_extra">
          <div class="gmail_quote">
            <blockquote class="gmail_quote" style="margin:0px 0px 0px
              0.8ex;border-left:1px solid
              rgb(204,204,204);padding-left:1ex">
              <div dir="ltr">
                <div class="gmail_extra">
                  <div class="gmail_quote">
                    <div><br>
                      <div>  class HelloView(View):<br>
                      </div>
                      <div>      __regid__ 'hello'<br>
                      </div>
                      <div>      __select__ = is_instance('IndexCard')
                        & title('summary')<br>
                      </div>
                      <div><br>
                              def render(self, cw, w, t, _, rset, *args,
                        **kw):<br>
                      </div>
                      <div>          with t.h1(_class=self.__regid__):<br>
                      </div>
                      <div>              w(_('Hello, World, says %s' % <a
                          moz-do-not-send="true"
                          href="http://cw.appli.name" target="_blank">cw.appli.name</a>))<br>
                      </div>
                      <div>          if cw.cnx.is_anonymous:<br>
                                      w(t.p('Register now and get a free
                        cw !'))<br>
                      </div>
                      <div>          cw.view('blogentry', rset)<br>
                        <br>
                      </div>
                    </div>
                  </div>
                </div>
              </div>
            </blockquote>
            <div><br>
              <br>
            </div>
            <div>This make me want to try:<br>
              <br>
            </div>
            <div>  @view('hello', is_instance('IndexCard') &
              title('summary'))<br>
            </div>
            <div>  def render(self, cw, w, t, _, rset, *args, *kw):<br>
                    with t.h1(_class=self.__regid__):<br>
              <div>          w(_('Hello, World, says %s' % <a
                  moz-do-not-send="true" href="http://cw.appli.name"
                  target="_blank">cw.appli.name</a>))<br>
              </div>
              <div>      if cw.cnx.is_anonymous:<br>
                          w(t.p('Register now and get a free cw !'))<br>
              </div>
                    cw.view('blogentry', rset)<br>
            </div>
          </div>
        </div>
      </div>
    </blockquote>
    <br>
    1) I think I disagree on the arguments you pass<br>
    2) Sounds like this make you want to try pyramid...<br>
    <br>
    1) The arguments<br>
    <br>
    I prefer when we pass what is strictly necessary only :<br>
    In the case of a single rendering function, what we need is :<br>
    - The data we render. This would be rset.<br>
    - The output stream w<br>
    - The tools we need to render : cnx or request (or, for views,
    something between both which I have trouble to define and I will
    call rendering_context), and cw.<br>
    <br>
    Also :<br>
    - cnx should not be an attribute of cw, but the other way around.<br>
    - it 't' is a cwtags object to produce tags, I don't think it should
    be here. An equivalent object accessible from 'w' could make sense.<br>
    - If we pass free functions as views, they do not need to become
    member method (ie, no 'self' needed).<br>
    - the identity informations should be bound to the request, even if
    the cnx has an identity.<br>
    - 'current' language is bound to the request, the view rendering
    context, or cnx.<br>
    <br>
    This would give :<br>
    <br>
    For a free rendering function :<br>
    <br>
    @view('hello', is_instance('IndexCard') & title('summary'))<br>
    def render(rendering_context, w, rset):<br>
        _ = rendering_context.i18n._<br>
        with w.h1(class_=rendering_context.view_regid):<br>
            w(_(u"Hello World, says
    {}".format(rendering_context.cw.appli.name)))<br>
        if rendering_context.identity.is_anonymous:<br>
            w.p(_(u"Register now and get a free cw:"))<br>
        rendering_context.view('blogentry', rset)<br>
    <br>
    For a class view:<br>
    <br>
    @view('hello', is_instance('IndexCard') & title('summary'))<br>
    class Hello(object):<br>
        def __init__(self, rendering_context, w, rset):<br>
            self.ctx = rendering_context<br>
            self.w = w<br>
            self.rset = rset<br>
            self._ = self.ctx.i18n._<br>
    <br>
        def __call__(self):<br>
            w, u = self.w, self._<br>
            with w.h1(class_=self.ctx.view_regid):<br>
                w(_(u"Hello World, says
    {}".format(self.ctx.cw.appli.name)))<br>
            if self.ctx.identity.is_anonymous:<br>
                w.p(_(u"Register now and get a free cw:"))<br>
            self.ctx.view('blogentry', rset)<br>
    <br>
    <br>
    2) Pyramid-likeliness<br>
    <br>
    What you almost suggest is that the regid and the selector don't
    belong to the appobject itself but to its registration.<br>
    Putting it this way would make it more natural to switch from
    classes to simple functions when it's enough.<br>
    <br>
    In pyramid, the views (which strictly correspond to what cw
    controllers are) can be functions or classes.<br>
    The selection predicates are not part of the view itself but are
    given to the 'add_view' api, which register the view.<br>
    The views take, as arguments, a request object and an optional
    context (in cw it is the rset).<br>
    <br>
    When the view is a function, it is defined like this :<br>
    <br>
        def some_function(request, context):<br>
            return response<br>
    <br>
    When it is a class :<br>
    <br>
        class SomeClassView(object):<br>
            def __init__(self, request, context):<br>
                # ...<br>
    <br>
            def __call__(self):<br>
                return response<br>
    <br>
    The advantage of class views is that they facilitate the reuse of
    code chunks from one class to another.<br>
    <br>
    My point is that CW is very close to this pattern, except that :<br>
    - the parameters fed to the __call__ function (or its equivalent
    'publish', 'render' etc) are often the same as the ones passed to
    the constructor.<br>
    - the regid and the selectors are on the class itself<br>
    <br>
    <br>
    I think that pyramid is a good example of working patterns that are
    close to CW, and should be at least a source of inspiration for
    designing the future CW (if not a base by itself but that's another
    challenge and I want to experiment first).<br>
    <br>
    <br>
    My few iconoclasts cents :-)<br>
    <br>
    Christophe<br>
  </body>
</html>