Template skeleton!

Nao

  • Dadman with a boy
  • Posts: 16,082
Re: Template skeleton!
« Reply #60, on September 29th, 2011, 07:56 PM »
Hassle? For me? Are you kidding, template skeleton is my best idea since wecss and is even funnier to work on ;)

I'm just at a loss when it comes to turning the stuff into an object but I'm sure it'll be a good thing eventually. At least for readability.

Arantor

  • As powerful as possible, as complex as necessary.
  • Posts: 14,278
Re: Template skeleton!
« Reply #61, on September 29th, 2011, 08:06 PM »
Heh, I know what you mean!

Objectifying the template skeleton... hmm.

Well, let's say it's wetpl. What does wetpl need to know or keep control of that nothing else should be controlling or dealing with? Seems to me that it needs to be aware of the context vars attached to the skeleton.

So that means we have a class and it has its own variables that are internal. Since we don't want to allow access to any old routine, it'd be a private variable of the class.

We'd then create a function for querying the skeleton, whose purpose, essentially, is to just return that variable. (This is known as a getter, or accessor, method)

Then you'd create functions under the class that essentially do what loadBlock does now, but there's the difference that instead of having to modify $context, when you're inside the function, you also get $this, allowing you to refer to the internal variable(s).

Really, it'd still be basically the same as loadBlock now, except that it would belong solely to wetpl and it would be able to modify the private variables to prevent anything else touching or breaking them, because you're forcing any changes to go through the methods you've given everything else to use.
When we unite against a common enemy that attacks our ethos, it nurtures group solidarity. Trolls are sensational, yes, but we keep everyone honest. | Game Memorial

Nao

  • Dadman with a boy
  • Posts: 16,082
Re: Template skeleton!
« Reply #62, on September 29th, 2011, 09:26 PM »
Quote from Arantor on September 29th, 2011, 08:06 PM
Well, let's say it's wetpl.
wetem! :P
Quote
What does wetpl need to know or keep control of that nothing else should be controlling or dealing with? Seems to me that it needs to be aware of the context vars attached to the skeleton.
Well, I don't see any reason to have $context['layers'] and $context['skeleton_array'] outside of the object...
As for $context['skeleton'], it can easily be modified to call an object setter instead.
Quote
Really, it'd still be basically the same as loadBlock now, except that it would belong solely to wetpl and it would be able to modify the private variables to prevent anything else touching or breaking them, because you're forcing any changes to go through the methods you've given everything else to use.
That was your main point for turning it into an object, yes.
And I don't mind doing it one way or the other. ;)

Okay, I haven't added that 'from_end' code yet, because that would probably require renaming the other entries...
Like:

      add         add block(s) at the end of the layer               <layer> <other /> <blocks /> </layer>
      first      add block(s) at the beginning of the layer            <layer> <blocks /> <other /> </layer>

Arantor

  • As powerful as possible, as complex as necessary.
  • Posts: 14,278
Re: Template skeleton!
« Reply #63, on September 29th, 2011, 09:34 PM »
Well, not only is it cleaner and 'safer', it is more semantic because you never have to worry about what a random loadBlock function is doing to global variables and it can't be tampered with accidentally by the same.

I'm fine with doing it either way, but if it is going to become wetem, it should be done sooner rather than later, since the last thing I want to have to do is get a publicly-usable release out, ship some add-ons, and have to rejig everything heavily after.

Nao

  • Dadman with a boy
  • Posts: 16,082
Re: Template skeleton!
« Reply #64, on September 29th, 2011, 09:56 PM »
Yeah, whatever name, but "wetem" is pronounceable in French at least :p

"weske", maybe...? :^^;:

Arantor

  • As powerful as possible, as complex as necessary.
  • Posts: 14,278
Re: Template skeleton!
« Reply #65, on September 29th, 2011, 10:07 PM »
The name isn't critically important, the idea behind it is. wetem is fine with me, weske reminds me of Hesk which I'd rather not be reminded of, thanks. Ugly ugly ugly.
Re: Template skeleton!
« Reply #66, on October 2nd, 2011, 06:09 PM »
OK, I think I found a limitation in the template skeleton, unless I'm missing something fairly big.

For my first plugin, I tackled a simple version of the 'users online today' functionality. Nothing clever, just literally getting all the visitors since midnight (subject to visibility)

Now, adding the template layer to the info_center layer is straightforward enough, but I can't place it before a given block inside that layer; ideally I'd place it after info_center->info_center_usersonline, but I can't see a way of doing that.[1]

Also, I'm thinking it might be useful to add a boolean return to loadBlock and its friends, in case we attempt to load but it isn't there - e.g. if the info_center->info_center_usersonline block doesn't exist, we would be able to detect that and display it somewhere else, or do something else with it at least.[2]
 1. It wouldn't be so much of a problem if it wasn't for the fact that there is actually already a block under usersonline, even if it is off by default.
 2. E.g. we could test for it up front and if not found, don't bother running the DB queries and so on.

Nao

  • Dadman with a boy
  • Posts: 16,082
Re: Template skeleton!
« Reply #67, on October 2nd, 2011, 06:15 PM »
loadBlock('my_block', 'info_center_useronline', 'after');

As the documentation says, 'before' and 'after' both accept either a layer or block name, unlike other options which require a layer name.

Boolean? Well, I thought that providing fallbacks would make more sense... (?)

Arantor

  • As powerful as possible, as complex as necessary.
  • Posts: 14,278
Re: Template skeleton!
« Reply #68, on October 2nd, 2011, 06:24 PM »
Quote
loadBlock('my_block', 'info_center_useronline', 'after');
Doesn't work, it just does nothing (this was the very first thing I tried). info_center_usersonline isn't a layer, it's a block. The code only works on adding a block after a layer, not adding a block to the same layer to which the specified block is in.

See the opening to loadBlock: it converts the target (info_center_usersonline) into an array and attempts to match that to $context['layers'], which if it found it, it would put it in $to, but it doesn't find it (because it's not a layer) and promptly returns.

Providing a fallback is fine, assuming it actually wants to do that. It might decide that if the desired place can't be done, it doesn't want to do a fallback - or, slightly more irritatingly, let's take something I considered for WedgeDesk. WD has a two column layout for the main ticket display, some of which I pushed into the sidebar - but if the sidebar doesn't exist, I'd be wanting to create a new template layer to hold things in. (Though, I guess, I could test for the sidebar before trying to add that block in the first place, but my point is: I might want to do other things rather than just having a direct fallback.)

Nao

  • Dadman with a boy
  • Posts: 16,082
Re: Template skeleton!
« Reply #69, on October 2nd, 2011, 07:02 PM »
Will fix ASAP then.
Last time I tested, it worked. I probably broke it during one of my numerous code changes last month.
Posted: October 2nd, 2011, 06:49 PM

Okay, gotta go, will commit a fix later...
I'm not sure how to deal with it though. I should probably just skip the original test if we're in before or after mode...

Arantor

  • As powerful as possible, as complex as necessary.
  • Posts: 14,278
Re: Template skeleton!
« Reply #70, on October 10th, 2011, 01:15 AM »
OK, so now I'm playing with it again, and either I'm missing something or it's still buggy. Right now it could just as easily be me, I'm not feeling 100% (it's gone midnight, the heating's off and yet I'm running a temperature to the point where I'm sweating :/)

Anyway, here's the deal. I'm hacking together a crude Share Topic plugin. Provides links to the FB like button, the Tweet button and the Google +1 button, at a topic level. It's also gotten me to create a new item at the top level for the admin panel where I've found a bug, too.

Now, because I like compartmentalising and easy-extension later, I put each of the three link buttons into their own mini template, and bind them into a custom layer that I add dynamically. For the sidebar it's just not a problem at all to do this, and it works just great adding my new layer as lastchild to the sidebar layer.

It's a bit more problematic adding it into the display template. Now, I seem to recall there being a discussion about mixing layers and blocks, and I was of the understanding that I could essentially create a layout like this:

default layer
  block
  block
  layer
    block
    block
  end layer
  block
end default layer

So there's me trying to add it into the template skeleton with:
Code: [Select]
loadLayer('flitter_topic', 'title_upper', 'before');

To me, this should include the layer into the flow before the title_upper (where the upper title/nav links are, after the report-sent and draft-saved blocks occur), but it doesn't do anything.

Now, it may be that it's not supposed to be used that way, and I have it wrong. Or it may be that it's got a bug. At this stage I'm not particularly fussed which it is, because I can make it all work with:
Code: [Select]
loadLayer('flitter_topic', 'default', 'firstchild');

It's not exactly the same but for the vast majority of the time, it's close enough. And of course I could easily enough rewrite it to use a block there which should work (haven't retested that yet) But I thought I'd clarify what it was supposed to do before I looked at changing it.

Nao

  • Dadman with a boy
  • Posts: 16,082
Re: Template skeleton!
« Reply #71, on October 10th, 2011, 09:09 AM »
It's not a bug, actually... It's as designed. loadLayer() is not supposed to be able to add layers relative to blocks, only to layers.
However, I'm aware that loadBlock() can do it for both blocks and layers, so it only makes sense to allow the same level of creativity for loadLayer(), so I'll look into it.

I'm also looking into, maybe fusing both functions into a 'load' function (wetem::load?) that will take care of inserting a block, layer or array of blocks and layers into a specific position.
I think it'd probably make sense to have something like this...

wetem::load(
  array(
    'layer' => array(),
    'layer2' => array(
     'block',
    ),
    'block2',
  ),
  'default',
  'add'
);

What do you think...?
The only 'issue' is that I'll have to analyze the array to create a new 'proper' array that looks like what's actually in use in the skeleton array:

  array(
    'layer' => array(),
    'layer2' => array(
     'block' => 1,
    ),
    'block2' => 1,
  )

i.e. flip block items (and these only), but recursively... (Added benefit: can possibly add some kind of sanitization later on.)
Or I could change the skeleton code to actually do it the other way around, hence removing the need to flip anything... (But no sanitization, of course.)

What do you think?

Posted: October 10th, 2011, 09:07 AM


PS: the use of wetem::load would also imply we couldn't load a layer by just specifying a string, it would have to be array('layer' => array()), but we could either add aliases to that, or simply rely on the fact that no one ever adds a layer without also specifying at least a sub-block at the same time...

Arantor

  • As powerful as possible, as complex as necessary.
  • Posts: 14,278
Re: Template skeleton!
« Reply #72, on October 10th, 2011, 09:13 AM »
Ah, so it was me misinterpreting, my bad.

I always thought of layers as being essentially blocks that contain other blocks; there's no real special layer-only behaviour that doesn't logically also apply to blocks, with the exception of being a parent. So yeah, a single fused function would be pretty neat.

I'd also suggest that it is done using flipping and is done that way to allow for sanitisation, though that's just my gut instinct, there's no real reason to insist on it (much as there wasn't much need to sanitise what went into the old template_layers setup)
Quote
PS: the use of wetem::load would also imply we couldn't load a layer by just specifying a string, it would have to be array('layer' => array()), but we could either add aliases to that, or simply rely on the fact that no one ever adds a layer without also specifying at least a sub-block at the same time...
I'm good with it being an empty array. I'd rather not enforce there being a sub-block defined by necessity.

Nao

  • Dadman with a boy
  • Posts: 16,082
Re: Template skeleton!
« Reply #73, on October 10th, 2011, 09:19 AM »
Quote from Arantor on October 10th, 2011, 09:13 AM
Ah, so it was me misinterpreting, my bad.
I should be apologizing for making the system not very logical when it comes to this... There is absolutely no valid reason for allowing blocks to be added relative to blocks and layers, but be more restrictive about layers.
Quote
I always thought of layers as being essentially blocks that contain other blocks; there's no real special layer-only behaviour that doesn't logically also apply to blocks, with the exception of being a parent. So yeah, a single fused function would be pretty neat.
Yep. I think it simply goes to show that my concept of template skeleton, while innovative, was a bit restrained by my earlier conception of how SMF's template system was working, i.e. layers were "the big thing" and subtemplates were more casual. The skeleton's target was precisely to allow for layers to become as casual as the rest, but I just didn't realize I was separating layers from blocks simply by having them in a different function.
Somehow, then, it makes sense to declare them as an array in wetem::load() because it shows anyone reading the code that this is a container for blocks.
Quote
I'd also suggest that it is done using flipping and is done that way to allow for sanitisation, though that's just my gut instinct, there's no real reason to insist on it (much as there wasn't much need to sanitise what went into the old template_layers setup)
It's not a big function, it can always be changed later.

Oh my, if only I could do it myself... I mean, put the template code into an object...
Heck, I'll just look at the other objects and give it a try. The skeleton is so dying to be an object...
Quote from Nao on October 10th, 2011, 09:09 AM
PS: the use of wetem::load would also imply we couldn't load a layer by just specifying a string, it would have to be array('layer' => array()), but we could either add aliases to that, or simply rely on the fact that no one ever adds a layer without also specifying at least a sub-block at the same time...
Actually loadLayer is only used 10 times, and half the time it's used for loading a block in it immediately after, but the rest of the time it's used to add a parent layer to the default layer, when building the template for a specific feature. I forgot about that... But it's still no big deal, and we could always add a wetem::layer() shortcut.

Arantor

  • As powerful as possible, as complex as necessary.
  • Posts: 14,278
Re: Template skeleton!
« Reply #74, on October 10th, 2011, 09:31 AM »
Quote
I should be apologizing for making the system not very logical when it comes to this... There is absolutely no valid reason for allowing blocks to be added relative to blocks and layers, but be more restrictive about layers.
I didn't discover it either until I started to use it, because I saw layers as this immutable concept...
Quote
Yep. I think it simply goes to show that my concept of template skeleton, while innovative, was a bit restrained by my earlier conception of how SMF's template system was working, i.e. layers were "the big thing" and subtemplates were more casual.
I actually thought the same to start with, and somewhere I managed to forget that, probably around the time I realised that from a plugin author's POV, there's no difference, and that a layer is semantically a block that can contain other blocks.
Quote
Oh my, if only I could do it myself... I mean, put the template code into an object...
Heck, I'll just look at the other objects and give it a try. The skeleton is so dying to be an object...
Look at wesql, it's really similar structurally in this case. There's private variables (much like the template skeleton itself should be as only wetem needs to deal with it), the setup stuff and then public functions.