Using functions for HTML generation


(Alexander Makarov) #1

Currently we’re using a helper class called Html so in the views it looks like:

<?php
use Yiisoft/Html/Html;
?>

<?= Html::input($bla, $bla) ?>

There is a technical possibility to do it via functions:

<?php
use function Yiisoft/Html/input;
?>

<?= input($bla, $bla) ?>

What do you prefer?

  • Static methods grouped in classes as in Yii 2
  • Namespaced functions

0 voters


#2

How does autoloading will work in second case?


(Alexander Makarov) #3

Via Composer: https://getcomposer.org/doc/04-schema.md#files


#4

This is not a real autoloading - these files are loaded on every request, even if these functions are never used.


(Alexander Makarov) #5

Yes, that is correct.


(Wilmer Arambula) #6

When changing the whole syntax of Yii2, many will not approach Yii3, the migration will only be mental, the entire application code must be rewritten, in that case it is better to do it again.


(Lubosdz) #7

Is following not possible?

use Yiisoft/Html;
<?= Html::input($bla, $bla) ?>

(Alexander Makarov) #8

Technically it is possible but means that namespace for the package should be just Yiisoft. I prefer to avoid that and stick to https://github.com/yiisoft/docs/blob/master/004-namespaces.md


#9

Does injecting HTML helper as insatiable object to View was ever considered?

$this->html->input($bla, $bla)

or

$html->input($bla, $bla)

This could allow to switch between helper implementation without changing view itself (for example switching between TB 3 and TB 4 may require only changing HTML helper used by view component).


(muitosefala) #10

Hi,
I was reading and passed my mind something maybe absolutely stupid but, I will say it.
Could it be possible to, try to imagine, as we are using Yii, in all project, that we do not need to declare the use of any particular yii core related package, and it will detect the use and load only what is needed? Sorry, I may be doing Sci-Fi here, but it occurred me. :slight_smile:


(Alexander Makarov) #11

Yes. During Yii 2 development. Disadvantages were:

  1. More to type: $this->html->input() vs Html::input(). Considering namespace it’s nearly the same but namespace could be imported once and $this reference can not. In case of $html there could be naming conflict since variable name is common.
  2. Needs extra annotation (not a problem nowadays).
  3. HTML is often used in other places: widgets, emails, push notifications etc.
  4. View is, sometimes, used without HTML such as push notifications or SMS templates.

No, it won’t work like that. Try replacing Bootstrap helpers with Bootstrap4 helpers in current Yii 2 project and you won’t get it working immediately. You have to adjust plain HTML with bootstrap classes as well.


(Alexander Makarov) #12

Would you please elaborate?


#13

$html->input() is almost the same as Html::input().
$html could be injected only in there is no such variable used in view - in this case user need to use $this->html->input(). This could also allow overwriting used helper at controller level - you can inject custom helper on render() call.
At worst case user could just use $html = $this->html; at the top of the view to create shortcut with any name - same as import.

I don’t get rest of the points, they don’t look like a problems to me.

This is matter of proper abstraction. Right now in Yii 2 this is not even a goal, because it is impossible due architectural decisions (static calls to helpers - you cannot configure it in any way, so you just continue hardcoding stuff). By using insatiable helper this will become possible and most of bootstrap specific raw HTML could be replaced by constants and or method calls.


(muitosefala) #14

@samdark, first, consider me like a newbie as I really don’t understand or know all the working processes of yii and all implemented things yet. I will try to elaborate.
I do lot of self brainstorm, I like to think and consider in first steps, all possibilities, even if they present to be stratosphere bullshit thoughts that will be outed, this is my basic way of starting ideas, so, what occurred to me was:

  1. We could only declare use yii; or even not.
  2. The Core could have a ''something as a controller" or else, that monitorize what is installed or present in core, as for extensions for example. By mapping it or else, using the error ability, like when we do not declare it and debug throw ‘not finding class or package’ for example or else, to map what is present and to load it as written code ir requiring. could be at runtime or not. could be like a debug thing but used as a loader… Well I am not being good at describing the idea right now, I am mixing too much concepts… I will do think better and elaborate better.
    Also may this not make you waste time, it was just a thought. :wink:

(muitosefala) #15

What I meant was, when you are creating a project in yii you will use it functionalities from core and framework packages, why do we need to declare all of them always?
If Helpers are part of core or part of framework, for example, we should not need to declare it use of.
The core or framework should manage the usage instead of throwing errors only, and auto-declare the use if found and needed.
So if it could be done like I am describing, it should be done by just calling as described for via functions: <?= input($bla, $bla) ?>
And not only for HTML, it could be done for anything from the yii framework, but I don’t know how it could be implemented nor if it would conflicts with other things. Yeah lots of Sci-fi here :smiley:
Cheers


(Alexander Makarov) #16

@muitosefala what you describe is importing functions. Technically it is easy as I’ve mentioned above. No having to import functions means these are global but that creates many possibilities for conflicts especially considering extensions. Namespacing functions is not really possible without use or fully qualified names.


(Alexander Makarov) #17

What you propose makes sense.

View could have a method such as setDefaultParameters() that we can configure via container:

\Yiisoft\View\WebView::class => [
    '__class' => \Yiisoft\View\WebView::class,
    'setDefaultParameters()' => [
        'html' => Reference::to(\Yiisoft\Html\Html::class),
    ],
]

\Yiisoft\Html\Html should be non-static class then.


#18

We could keep it static - then helper could be used statically without instantiation (Html::input()) and from instance ($html::input()).


(Alexander Makarov) #19

That sounds interesting but one thing is still the issue. In order to get code completion in IDEs you have to do:

<?php
/** @var \Yiisoft\Html\Html $html */
?>

That is pretty similar effort-wise to importing with use.


#20

So with the same effort you will get much more possibilities. Is it really an issue? :stuck_out_tongue:

I’m more concerned about additional complicity and things that could be broken by configuration. For example if we allow to configure list of variables injected to view by setDefaultParameters(), you cannot be sure that $html exists and that it contains (correct) HTML helper.