daokoder / dao-modules

Dao Standard Modules
http://daovm.net
12 stars 5 forks source link

Enhancement: allow nested contexts in web.html #77

Closed dumblob closed 9 years ago

dumblob commented 9 years ago

I've reconsidered the requirement of having nested contexts and even though we already discussed this issue somewhere, I'm absolutely sure, supporting nested contexts is a must.

Because of the nature of the web.html module, it's hard to work with similar subtrees if one doesn't want to duplicate code. For this purpose, anonymous routines are a well-fitting solution, but they can't be used, because calling fragment(){} in an existing context is not supported. Consider the following simple example, where I can't think of any better abstraction.

document {
  my_context = ...
  ...  # some long document stuff changing my_context
  put_one_x = routine(x) => string {
    return fragment {
      div(id=x.id) {
        anchor(href=x.uri.img) {x.uri.lbl}
      ...  # and lots of other stuff
      }
    }
  }
  # get_list_of_x() returns a long list of tuples
  for (x in get_list_of_x(my_context)) {
    text(put_one_x(x))
  }
}
Night-walker commented 9 years ago

I'm not sure why you're trying to envelop the similar stuff into extra fragment(). It should work pretty well without it.

dumblob commented 9 years ago

Right, I simplified the example too much and didn't notice ;) In practice I have something like:

document {
  my_context = ...
  ...  # some long document stuff changing my_context
  put_one_x = routine(x) => string {
    return fragment {
      div(id=x.id) {
        anchor(href=x.uri.img) {x.uri.lbl}
      ...  # and lots of other stuff
      }
    }
  }
  div(id='00') {
    ...  # some stuff
    div(id='000' {
      ... # some stuff
      # get_list_of_x() returns a long list of tuples
      for (x in get_list_of_x(my_context)) {
        text(put_one_x(x))
      }
    }
  }
  ...  # some stuff changing my_context
  div(id='01') {
    ...  # some stuff
    div(id='011' {
      ... # some stuff
      for (x in get_list_of_x(my_context)) {
        text(put_one_x(x))
      }
    }
  }
  ...  # some stuff changing my_context
  div(id='02') {
    ...  # some stuff
    div(id='022' {
      ... # some stuff
      for (x in get_list_of_x(my_context)) {
        text(put_one_x(x))
      }
    }
  }
  ...  # some stuff changing my_context
  ...  # other similar div sections
}
Night-walker commented 9 years ago

I still don't see why put_one_x() has to create new fragment which then gets inlined into the document without any post-processing or so. fragment() and text() are redundant in this example just as in the former one.

dumblob commented 9 years ago

Technically yes, but I thought, that the purpose of fragment(){} is to encapsulate tags and allow these groups to exist individually. In the case I've shown it's not yet necessary, but the idea is to have absolutely independent pieces of code, which can be thrown here and there without taking care what is inside.

On the other hand, it's fairly easy to write fragment { put_one_x() } or document { put_one_x() } instead of justput_one_x()` and it actually seems even a little bit clearer to me. So I'm closing this issue as my arguments do not seem to be strong enough :wink:.

Night-walker commented 9 years ago

Technically yes, but I thought, that the purpose of fragment(){} is to encapsulate tags and allow these groups to exist individually. In the case I've shown it's not yet necessary, but the idea is to have absolutely independent pieces of code, which can be thrown here and there without taking care what is inside.

The only purpose of fragment() is triggering the serialization. You don't need to call it for any other purpose, 'independent pieces of code' can exist fine without it.

On the other hand, it's fairly easy to write fragment { put_one_x() } or document { put_one_x() } instead of justput_one_x()` and it actually seems even a little bit clearer to me. So I'm closing this issue as my arguments do not seem to be strong enough .

fragment() is not needed in the examples you showed. You can just throw it out together with subsequent text() and it should work.

dumblob commented 9 years ago

`fragment() is not needed in the examples you showed.

Yes, I meant separate documents, not the inappropriate examples I showed.

Night-walker commented 9 years ago

Anyway, unless you need to generate multiple documents simultaneously (in which case you can just spawn more tasklets), no nested contexts should be necessary.

dumblob commented 9 years ago

generate multiple documents simultaneously in which case you can just spawn more tasklets

I'll do as generating multiple documents simultaneously is what I actually want to achieve.