The latest share stream feature required quite a few changes on the app to enable all the flexibility. Under the hood the same template is used to display a stream (or a message) no matter how it's being accessed. That's quite a lot of conditionals, but usually the problem is not with having conditional blocks but around having cryptic conditions that power them. I've seen it some many times - you open a template and see something like {{ if and .OneCondition (and .User .SecondCondition) (not .AnotherRandomCondition }}
. The only feeling you get is the one of desperation since there is no reasonable way to change this condition without breaking things, especially if the template is used in several places.
The approach I took was to switch from ad hoc conditions to a capabilities based approach. For a given stream there is a set of flags which defines what a user can do with a stream - can they read? Can they add changes? Is it their own stream? With this approach the complexity in the templates goes back to a bearable level.
Another point to address is to synchronize the conditions in the template with the ones in the backend code. What I did in my case was I extracted all the code that calculates user capabilities into a single function that does all the calculations and use it both to control the behavior in the templates and the behavior on the backend. With that move the code became even simpler