Template skeleton!

Nao

  • Dadman with a boy
  • Posts: 16,082
Re: Template skeleton!
« Reply #15, on September 7th, 2011, 09:25 AM »
I'd just tend to have this philosophy: don't waste CPU cycles fixing crap made by badly coded mods or themes.

Btw I also tend to forget to update your documentation when I remove stuff hehe. For instance it referred to include_after_template which doesn't even exist anymore so I removed it ;)

I guess that, somehow, the tempting system could use a diet. Like so many other things you already did!
Posted: September 7th, 2011, 09:23 AM

Btw - use default images AND templates? That's skin territory to me ;)
Re: Template skeleton!
« Reply #16, on September 7th, 2011, 06:37 PM »
Quote from Bloc on September 7th, 2011, 10:47 AM
I never got the idea behind using default theme for images..
I don't know, I thought new themes used default images by default... (i.e. if no images folder was found, the default images folder was used.) Isn't that the case...?
Quote
no themes use it, and not many use the based-on option either. Whats important is that the fallback tempaltes are self-contained, so if a custom theme rewrites everything in index.tempalte, possibly display.tempalte, the others would still work.
Yeah, unless they broke the main template of course... In which case they'll see soon enough, anyway.
Quote
In the beginning I argued sepatating styles, or at least use alot of common classes. Both was worked out to be one-file-fits all and maybe 10% classes, the rest is id styles.
The early Curves (the ones you made) were pretty light on the CSS. Like, 4 times less... Although it's a nice idea to make everything skinnable, the SMF team put too much emphasis on the "everything", and less on the "skinnable", because as it is now, it's a real mess to navigate through the CSS and find what you want to change. Which is one of the reasons why I went for the pre-parser, which at least allows for shorter code and more logical nesting. Unfortunately I don't have the time to rewrite ALL of the css... There are many places where, frankly, common classes would make more sense to use -- if only in the admin area, because no one in their right mind would reskin this anyway...
Heck, even the actual common classes (windowbg*, clear_*, float*...) didn't get used all of the time.
Quote
Wasting a lot of good styles on things designers seldom change anyway, making working with index.css a nightmare really.. Its like it was all - or nothing lol.
Absolutely.
I'd tend to say -- feel free to simplify the Wedge CSS, reapply things to the HTML and not always the CSS... You can always submit a patch and I'll happily look through it :) I'm all for the simplification of code -- I just can't do it alone because I have more things to do and they're not all layout-related.

Okay, my progress on this...

- Wine is working. Some subtemplates won't show, because I haven't yet converted the 'sub_template'/'template_layers' code to use the array.

- The skeleton override is working. The skeleton is rewritten to fit my HTML tags. Here's the code I put into Warm's skin.xml:

Code: [Select]
<!--
Layout skeleton. The following uses pseudo-HTML to represent the final array.
- use <tags></tags> to define layers (i.e. a function
  called as a wrapper around other functions)
- use <self closing tags /> to define sub-templates

Overrides the theme's $context['skeleton'] variable.
-->

<skeleton>
<html>
<body>
<wrapper>
<sidebar>
<sidebar_feed />
</sidebar>
<header />
<menu />
<linktree />
<top></top>
<main>
<content />
</main>
<footer />
</wrapper>
</body>
</html>
</skeleton>

As you can see, it's dead simple... Feel free to suggest any improvements, in case I missed anything. (The indentations are only there for clarity. Obviously they're not needed...)

Also, the rendering for this rewritten skeleton is buggy. It still uses the other one... Uh.
And the db_debug_junk is output at the beginning instead of the end, meaning the body tag closer isn't output at this point. Well, it's probably the kind of bug I'll spend an hour on, until I find out that I made a tiny mistake at one point and spend another hour cursing at myself... :lol:
Posted: September 7th, 2011, 06:35 PM

:edit: db_debug_junk issue fixed...

Arantor

  • As powerful as possible, as complex as necessary.
  • Posts: 14,278
Re: Template skeleton!
« Reply #17, on September 7th, 2011, 06:39 PM »
Quote
I don't know, I thought new themes used default images by default... (i.e. if no images folder was found, the default images folder was used.) Isn't that the case...?
No, it isn't. A new theme as created by the admin panel is a copy of all folders from the theme's directory, plus index.template.php.


OK, idiot question time, because I'm not seeing how the one thing that is quite important to me is covered.

I see there is the sidebar_feed item inside the sidebar. How do I go about adding a new item in sidebar, preferably doing it before sidebar_feed, and doing it dynamically because I don't want it every page?
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 #18, on September 7th, 2011, 06:55 PM »
Quote from Arantor on September 7th, 2011, 06:39 PM
OK, idiot question time, because I'm not seeing how the one thing that is quite important to me is covered.

I see there is the sidebar_feed item inside the sidebar. How do I go about adding a new item in sidebar, preferably doing it before sidebar_feed, and doing it dynamically because I don't want it every page?
This isn't done for now but I don't see where it's going to be a problem.
The skeleton array is generated right from loadTheme(), so basically everything you add to it later (via loadSubTemplate) will be added to the array by Wedge. It'll be transparent...
I can also add a removeSubTemplate() function.
I'll also add something like loadLayer(), although I don't exactly know how it'll work... (i.e. where do we position it?)

BTW, I just found out that there's a slight miscalculation in my project.
The skin.xml override is loaded through wedge_cache_css, which itself is loaded through theme_base_css, which itself is called "at the last possible minute"... Although this works quite well for all of the overrides it has (html blocks, etc.), rebuilding the skeleton at that time will delete all of the existing subtemplates.

Hmm...

Don't really know how to fix that -- except by loading the CSS files twice: once early on for the skeleton override, and once at the last minute for block overrides. Yikes.... :-/
Any idea? I'll take a cigarette break.
Re: Template skeleton!
« Reply #19, on September 7th, 2011, 11:03 PM »
Okay, I've done it -- split wedge_cache_css into two functions. The first one is called in loadTheme() and will build the correct list of CSS folders for use in skins (i.e. it will discard any parent folders if it meets a replace-type skin), and will retrieve the options for the current skin. The second one, wedge_cache_css, will go through the folder list built by the former function, and will build the actual CSS file. Performance-wise, it should be exactly the same as before, except that it's cleaner, and that it allows me to override the skeleton right after loading it from the theme. (Hmm, come to think of it... I should probably load the theme's skeleton after the skin's skeleton, to save on processing time... :lol:)
I'd have hoped this would make it easier to merge add_css_file with wedge_cache_css (their code is VERY similar), but it probably won't be possible, because each one has optimizations that the other couldn't use... I still have hope, though :P

Anyway... 'Done'.
Warm is running the modified skeleton, it has the sidebar on the left, but the rest of the content is crammed onto two vertical columns if the main content doesn't take much space (actually, it looks funny.) I guess I'll have to encase all of the content (and header, and footer) into their own div. Well, the structure isn't too great... I should probably add more layers, so that pretty much every block is encased within a special div that I can then manipulate as I wish.
That, or I actually allow adding functions within a file in the skin... Something like 'Custom.template.php', which would be loaded by Wedge at loadTheme time, and would contain overrides, i.e. "template_body_above_override". If such an override exists, Wedge won't run the original function. Of course, then, it's getting closer in spirit to a full-fledged new theme, and I don't know if I'm ready to make that big a jump...

Still got plenty left to do. Hopefully I'll be finished by tomorrow night... I'd really rather not spend too much time on this. I guess I can fix Warm later -- definitely not a priority (heck, I can simply remove the <skeleton> entry in skin.xml just to fix it for now...)

Arantor

  • As powerful as possible, as complex as necessary.
  • Posts: 14,278
Re: Template skeleton!
« Reply #20, on September 7th, 2011, 11:07 PM »
Sounds like a very awesome amount of functionality and very, very flexible too :)

Can't wait to actually see it to play with.

Nao

  • Dadman with a boy
  • Posts: 16,082
Re: Template skeleton!
« Reply #21, on September 7th, 2011, 11:11 PM »
I don't know if it's going to amount for new functionality, but it'll sure make more sense IMHO... *And* it'll make for easier debugging if you can't figure out why your block won't show up.

print_r($context['skeleton']);

Done... :lol:

Of course, adding ?debug or ;debug to the URL is also a nice solution. (I did it yesterday to debug the new stuff. I have no idea why it's not exactly a documented feature...)

Arantor

  • As powerful as possible, as complex as necessary.
  • Posts: 14,278
Re: Template skeleton!
« Reply #22, on September 7th, 2011, 11:15 PM »
Quote
I have no idea why it's not exactly a documented feature...
I don't know that either, but to be fair it's only really useful for themers and people that create template layers. Which means it's useful to themers and the dozen or so modders who ever bothered to investigate SMF and found it useful, which means Daniel15, various portal authors, me, you[1] and anyone else who really, really put time in.[2]

I sort of wondered about adding it to the debugging menu, but I figure it's convenient enough there. Or, alternatively, add it to $db_show_debug. If you're already using that, your layout's shot to hell anyway with masses more data than normal, why not go for the full house and do it then too?
 1. I saw its use in Aeva 2.x, thought it was ingenious.
 2. Oh, and one who only gets the title of modder in the strictly Darwinian sense, after observing a rival mod put in ads in an almost-totally-layers manner and seeing the mod they bought *not* do that. But we won't dwell on that.

Nao

  • Dadman with a boy
  • Posts: 16,082
Re: Template skeleton!
« Reply #23, on September 8th, 2011, 02:16 PM »
I'm hoping to have this on SVN by tonight...

Most of the stuff is working now. I'm having more issues though, so I'll just mention them here.

- seems like having a page sent in XML will crash everything. I've only seen this quickly, it seemed to me but it seems like XML will bypass many things in loadTheme() or something... (And it makes sense, since this codepath will generate its entire 'HTML' from scratch.)
Pete, any memories about this?

- I'm working on a "loadLayer()" function, similar to loadSubTemplate()... I'd like for it to be logical in its execution and settings. When exactly do we want to add a layer, and what for? Generally it's because we want to add something around the code being executed. The main issue I'm having here is that if it means adding a layer to the 'main' layer, any subsequent layers added will become parents of the earlier added layers. It's not a big problem to me but I don't think SMF does it in that direction... (Does it?)
Also, I'm having fun (ah ah... not exactly) trying to figure out how to quickly rename an array key. It's easy enough when your array doesn't need to preserve order... But when you start having to use array_splice when this one doesn't work with associative arrays and doesn't even preserve key names, meh... I guess I'll have to do my own routine that rebuilds an array from scratch. Ah ah, fun, as I said...

And these are my two current issues :P
Posted: September 8th, 2011, 01:58 PM

Okay, renaming keys was easy enough, surprisingly... And fast.

However now I'm wondering what's best. By default, layers are added to the 'main' layer (you can choose your target layer, otherwise it's not cool.)
Should they be added *inside* the layer, or *outside* it? i.e. adding a <layer2> to <main> in <layer1><main><output /></main></layer1> should result in what...?

<layer1>
  <main>
    <layer2></layer2>
    <output />
  </main>
</layer1>

<layer1>
  <main>
    <layer2>
      <output />
    </layer2>
  </main>
</layer1>

<layer1>
  <layer2>
    <main>
      <output />
    </main>
  </layer2>
</layer1>

Of course I can include an option to do any of the three, but I'm sure there's going to be at least one option that never gets used... And we're bound to find people complaining they can't add an empty layer at the *end* of an existing layer... :lol:
Oh well, maybe it's not very important... I mean, adding a layer to the end manually can be done very easily: $context['layers']['main']['my_layer'] = array();
And at the beginning, my first guess would be to do something like: $context['layers']['main'] = array('my_layer' => array()) + $context['layers']['main'];
(And yes, I suppose I can add wrappers for these, too...)
Re: Template skeleton!
« Reply #24, on September 8th, 2011, 02:29 PM »
Quote from Arantor on September 7th, 2011, 11:15 PM
I sort of wondered about adding it to the debugging menu, but I figure it's convenient enough there. Or, alternatively, add it to $db_show_debug. If you're already using that, your layout's shot to hell anyway with masses more data than normal, why not go for the full house and do it then too?
It's not shot to hell... It only adds below the end of the body. If it was shot to hell, I'd be out fixing it... :lol:
No, don't touch $db_show_debug, I always have it enabled, even if I don't use it, while ?debug would kill my layouts... :^^;:
Posted: September 8th, 2011, 02:18 PM
Quote from Bloc on September 8th, 2011, 01:10 AM
Layers are a really under-developed feature of SMF.
I actually didn't understand anything about layers and sub-templates before I started working on Wedge... Yikes.
Which is one of the reasons I thought that skeletons could sound more logical to newbie modders and themers.
Quote
The theme should have the last word(I know, I am repeating myself lol) so even if x layers are added in, it can still look good.
How would you see them have the 'last word'?
Adding a function somewhere at the end that allows for the theme to check for integrity...? :^^;:

Oh, which makes me think -- there is technically nothing that prevents me from doing all layer/sub-template operations directly on the pseudo-HTML that I provide in $context['skeleton']. I only converted it to an array to make it more 'logical' for parsing by users, but if I add enough wrapper functions, I can do everything myself with regular expressions...
I don't know what's best for this. I'm currently sticking to the array solution, but I guess it's not going to take a long time to rework everything into using a HTML string if needed.
Quote
And no mod would ever take control over it in such a way it does in SMF now, it should not have to. A portal needs sidebars? in SMF: wrap everything else, or possibly just the content into a table..voila. But problem comes when the theme doesn't know about the sidebars, and puts for example absolute positioned items on the sides..a nice way to add embelishments around the content. But now it is separated from that crafted background around the content, by 2 big bars...
Well, I don't really have a suggestion on how to fix this (plus, Pete seems to have the problem in WedgeDesk itself ;))
Do you have anything...?
Multiplying the number of layers, maybe? And putting your positioned stuff in one of the top-level ones, and hoping that mods will only built upon lower-level layers?
Quote
If the theme had KNOWN there would be layers that could want to add themselves on the sides, it would have made some changes for that.
But, doesn't SMF already allow themes to know that...? It's all in $context['template_layers'] AFAIK...? And it's easy than Wedge, because template_layers is a single-dimensional string, basically a set of Matryoshka dolls that can easily be analyzed, while Wedge now has a more complex multi-level structure. So I don't know that my thing will be 'the' solution at all for this kind of issue...

I'm all ears though, if you have any suggestion, however little it is. I'm not building this system for myself but for themers -- no, not themers -- for *designers*. To give complete freedom on the layout, which usually isn't possible without redoing a new theme, i.e. getting into compatibility problems.
Quote
Sadly this is just things that theme designers worry about, and not many of them either, at least not for SMF. So it will most likely never win any motions to be added.  Wedge looks to be heading in a good direction though.
I may not be a 'designer', but I'm a good listener when it comes to feature implementations, you should have suggested this kind of change long ago ;)

Arantor

  • As powerful as possible, as complex as necessary.
  • Posts: 14,278
Re: Template skeleton!
« Reply #25, on September 8th, 2011, 02:48 PM »
Quote
I've only seen this quickly, it seemed to me but it seems like XML will bypass many things in loadTheme() or something...
loadTheme should always be called, at least. But if $_REQUEST['xml'] is defined, hideChrome() is called, the Xml template is loaded, and the rest of the pure theme stuff (most importantly, loading any required templates and initialising template layers) doesn't happen.

After that, it sets up jQuery, and looks for the init subtemplate in a theme, sorts out blocks, then just wanders off on other stuff like dealing with scheduled and imperative queues, the mail queue and stuff like that, nothing that should be a problem here.

Anything in the error log?
Quote
any subsequent layers added will become parents of the earlier added layers. It's not a big problem to me but I don't think SMF does it in that direction... (Does it?)
No, any subsequent layers are children of the existing layer. Thus if you add a new layer to the default, you get html_before, body_before, newlayer_before, main, newlayer_after etc.
Quote
When exactly do we want to add a layer, and what for? Generally it's because we want to add something around the code being executed.
Yes, but we don't always want to layer things, which is where it gets complicated. The way I'd envisage using it normally is to have some content, encapsulated in markup (either a block or some other container) and inject that into the existing structure, which wouldn't necessarily constitute a layer.

The really important use is to be able to inject content into the sidebar, which notionally requires adding to the list of templates to be called by the sidebar layer, rather than creating new layers.[1]
Quote
Also, I'm having fun (ah ah... not exactly) trying to figure out how to quickly rename an array key.
There isn't a particularly quick way of doing it, to the best of my knowledge. All the methods for accessing arrays (even more exotic options like array_replace in 5.3) are for dealing with the values not the keys.

What about something like:
Code: [Select]
$keys = array_keys($original_array);
$values = array_values($original_array);
foreach ($keys as $key => $value)
  if ($value == $key_to_find)
  {
    $keys[$key] = $key_to_replace;
    break;
  }
$new_array = array_combine($keys, $values);

I don't know how efficient that'd be versus building a new array from scratch as a product of regular iteration of the original array, but that's the approach that occurs to me, anyway.
Quote
Okay, renaming keys was easy enough, surprisingly... And fast.
Oh, you already did it, heh.
Quote
Of course I can include an option to do any of the three, but I'm sure there's going to be at least one option that never gets used... And we're bound to find people complaining they can't add an empty layer at the *end* of an existing layer...
The facility would be useful, even if it ends up being underused, though adding a template to the end of a layer is significantly more important in the long run.

You and I are actually in agreement, though it might not look like it. You're right, it should need all 4 options, which are effectively: outside, inside, before-item, after-item.

In your examples, the first is before-item (it's before <output />), inside, outside (all considered relative to main), and the only item that's lacking is after-item, because positioning of templates is potentially quite important.

Remember: forcing everything to be actual layers is potentially a headache and one I don't want to repeat. See, if you provide the ability to place content with those 4 options, it doesn't matter if it's a layer or a self contained item.

The same logic should cover for adding <extra-content /> after <output />, the only difference is that extra-content isn't an array signifying a layer but a self contained item, right?
Quote
No, don't touch $db_show_debug, I always have it enabled, even if I don't use it, while ?debug would kill my layouts...
Fair call, I do the same :lol: Like I said, I was only considering it being part of db_show_debug, but it really should be in the debug menu (and I'd probably remove it from URLs and sessions otherwise if it were a modSetting)
Quote
but I guess it's not going to take a long time to rework everything into using a HTML string if needed.
Please please please leave it as an array. It can be built from a pseudo markup string in the skin file but it really should be an array internally because it's much faster to inject items into an array than it is to use string munging.
Quote
Well, I don't really have a suggestion on how to fix this (plus, Pete seems to have the problem in WedgeDesk
This is where themes and mods are always going to have problems, because there is no possible way that you can expect everything to work in a meaningful manner, there just isn't.[2]

What we can do, however, is be intelligent about it. The default theme has a sidebar. I have no problem with the theme indicating through some kind of variable that it provides a sidebar. Then WedgeDesk can check to see if a sidebar is given, and if it is, use it, otherwise I can reimplement the sidebar type bits that I had before (as in if the theme doesn't provide for one, I can)

Then you get more clever, because if/when a portal comes along, it can look at that too - if the theme provides a sidebar, make use of it, but if not, the portal can create one. It'll take a bit of co-operation to make it work but instead of going it alone as much as historically happened, I see no reason why we can't be a bit smarter about it.
Quote
So I don't know that my thing will be 'the' solution at all for this kind of issue...
From my standpoint, I think it is, because it provides the core with the facility to let designers be a lot more free - and it's not like it's some mythical resource.

All the time it's supported and there are add-ons using it rather than hacking templates about, it'll be an improvement. Sure there are going to be incompatibilities but that's a fact of life: it's going to happen that some things just don't play nicely. This, however, will really minimise that being a problem, IMO.
Quote
But, doesn't SMF already allow themes to know that...?
Themes dictate what layers they want used, which is typically html and body. They're the ones calling the shots, it's not like there is default skeleton in place that they can make use of - or totally ignore in favour of their own, and that's it.

It's not like there's any kind of structure to it, other than a fairly limited approach, but even that isn't used that much. By making it more powerful, and proceeding to actually *use* that power a lot more, I think we'll see more and more examples of it.

But ultimately it's going to rely on a certain set of contractual obligations - like I mentioned above with the 'supports sidebar' concept. Themes are going to need to indicate if they provide these things or not, and if not, mods that want to use them will need to do something else to accommodate it (or risk the outfall of incompatibility), and that's something that's just going to have to happen. We can't (and, IMO, shouldn't) dictate that every theme has to support a sidebar, it's not realistic to expect that.
 1. Even if it's physically implemented by new layers, the notion is that it would be a single encapsulated template within the sidebar layer, if that makes sense.
 2. Hint: even the magical holy fucking grail that is WordPress[1] has this issue where themes have to provide support for common widgets and vice versa.
 1. I meant that sarcastically. WP is not a holy grail in my eyes.

Nao

  • Dadman with a boy
  • Posts: 16,082
Re: Template skeleton!
« Reply #26, on September 8th, 2011, 11:34 PM »
Thursday, September 8, 2011. Paris time, 22:41.
The friggin' new layer system friggin' works in both Wine and Warm.

Oh yeah! :eheh:

It just keeps failing in XML but I think I'll commit it and look into this tomorrow, unless Pete finds a fix before me. (Hint, hint! :P) (And yes, I can simply avoid running this code for XML but I'd like to know where I made a mistake, if any...)
Posted: September 8th, 2011, 10:42 PM

(Hoping I can complete the changelog before I go to bed... It's really huge. Some of the files underwent a lot of changes, notably Load.php, Subs.php, Subs-Cache.php and the index template... I've done about two thirds of it.)

Arantor

  • As powerful as possible, as complex as necessary.
  • Posts: 14,278
Re: Template skeleton!
« Reply #27, on September 9th, 2011, 12:22 AM »
Quote
like portal A adds a "left" sidebar, ad mod B adds also a "left" panel but really want it the far left
And this is immediately where control at some level has to be asserted.

If you don't provide some modicum of control, you end up with the current mess where templates are trying to work around each other, to the point that you might as well not bother trying to do anything even remotely complex and just plump for sticking to the standard because anything else won't play nicely.

I spent a surprising amount of time debugging SD's layers interacting with the portals for just this reason.

If two things compete for the far left, what determines who wins?

Nao

  • Dadman with a boy
  • Posts: 16,082
Re: Template skeleton!
« Reply #28, on September 9th, 2011, 12:57 AM »
Skeleton = structure not position.
It's only a helper it won't do the cooking for you :)

Positioning is up to CSS. I'll commit on a few minutes. Bloc, I suggest you look into the new system and determine if you think something can be done with it. I'll accept any patches, algorithms or suggestions. With pleasure.
Posted: September 9th, 2011, 12:34 AM

It's up :)
Hopefully it'll work for both of you, Pete and Bjorn... Take your time to study it but make sure to feel your first feeling about it!
I'll try and update the demo site this week-end... I guess I'm going to have to release it to the public anyway. Ahhhh, and I'm still not using AeMe for avatars and attachments... The agony, I always postpone this big chunk!

Arantor

  • As powerful as possible, as complex as necessary.
  • Posts: 14,278
Re: Template skeleton!
« Reply #29, on September 9th, 2011, 12:59 AM »
Quote
Ahhhh, and I'm still not using AeMe for avatars and attachments... The agony, I always postpone this big chunk!
It's a huge job, no doubt, but I suspect it almost depends on the permissions system being upgraded to a degree.

Before worrying about implementation, nail down the exact details of how it's supposed to work, where avatars and attachments should be stored (one folder for each, multiple folders?), how that should be referenced in the code (new album, mythical album 0 or something else?) and stuff like that.

It's a complex job and it has consequences that are far reaching, so best to look at that first before touching the code, IMO.