I never managed to wrap my head around html_writer. I tried (and filed a couple of bugs, like
MDL-35307) but just couldn't cope with it. The amount of extra typing involved makes it very hard for me to read code using it, and the first thing I now do when trying to figure out what a renderer is actually doing is go through and manually translate all the html_writer::tags to something that I can read and map mentally back and forth between code and the output it produces.
I'm struggling for something constructive and useful to say since this is planted fairly deep and I don't think there's much chance of change. Let me see..., okay here goes but bear in mind this is from a programmer point of view, I realise it's tricky to be everything to everyone:
1. I think it would be better if the name html_writer was as short as possible e.g. out::tag, html::tag, h::tag tag::div as it's used all over the place so like common words in languages it should be short (same for get_string, which I've seen elsewhere as a single or double underscore e.g. _("hello")). It would be fairly easy to point both at the same function for a transition period.
2. It would be better if you didn't pass the tag name as a string as it allows difficult to catch typos, like html_writer::tag('dib', $etc. If it's html_writer::div($etc. then not only do you get some extra typo checking, but you've saved yourself three characters, two apostrophes a comma and a space (at a cost of an extra function calll, which PHP developers generally seem to be allergic to).
3. You shouldn't be using such low-level tag writing most of the time. If you're outputting a cancel button you should be calling a function and giving it the unique info it needs e.g. out::cancel_button($text) and all the muddling about with HTML should be hidden within that function, that means if you need to change all the cancel_buttons to have a different tag or class or wrapper or whatever you can do it in one place. This is very related to Amy Groshek's attempt to map out the disparate HTML used in Moodle and somewhat standardise it (see
https://moodle.org/mod/forum/discuss.php?d=216519 for more on that and Danny Wahl's comment in particular:
https://moodle.org/mod/forum/discuss.php?d=216519#p942924 is relevant to this). That encapsulation should carry on all the way up the stack, so if you need a warning dialog you should just give it the text, and it'll take care of calling the ok and cancel buttons which will then allow all dialogs to look and act the same and be themeable.
4. I don't know if it's too late for this, but as in my bug linked above, the one thing I really couldn't cope with was the attributes going at the end. My poor little brain just couldn't manage going from <div class="first">content</div> to html_writer::tag('div', $content, array('class'=>'first')) and back, especially when the $content was another set of tags.
I had a look to see if there was a widely used PHP library for this kind of thing but the only thing I found was twig templates which seemed a bit much for my own use.