Design strategy, when to use widget / helper ?

Hi !

I'm a RoR developer and I'm beginning with Yii. I want to create what I would call  (as a RoR dev) a helper to display Google Analytics tracking code on my page. To be reusable I need only one param, the trackerId (ex "UI-3438-34").

Should I use a widget or a simple "helper" ? My helper can render a view like a widget ?

Regards !

Raphael

You may insert your tracking code into your layout.

You may also want to add segments, so make sure your code doesn’t appear more than once across your application.

Thanks, I know I can add my analytics tracking code into my layout but I want to avoid having a lots of JS directly in my layout, for code clarity I prefer using helper / widget.

The question is still open even if my example is not good, the main problem is when to use helper and when to use widget.

As far as I know, Yii doesn’t have view helpers implemented in terms you mean it. However, it offers a good way to insert html tags for forms (have a look at CHtml class).

Widgets are often used to represent repeated small UI interfaces. (Like as Wordpress uses its internal sidebar widgets.)

You are recommended to create a widget for GA code, but also keep in mind, that if a single tracking code in your layout reduces code readability, you probably use far more JS code than you should.

(I’ve seen you’re not about to hardcode the tracking ID. I would’ve suggested that too.)

I have no JS at all for the moment :wink: I begin with Yii and I want to begin by "the  yii way" even if I come from Rails.

So widget should be used for things with more complex than just displaying a simple output.

What I want (in this case) is more something like CHtml helper.

Thanks for your help !

I've finally ended by doing this :

  • create a helpers folder in my protected folder
  • add 'application.helpers.*' in import of main.php

For example I've added a CGoogleAnalytics.php file which contains :



<?php





class CGoogleAnalytics


{


  public static function tracker($id)


  {


    echo '


    <script type="text/javascript">


      var gaJsHost = (("https:" == document.location.protocol) ? "https://ssl." : "http://www.");


      document.write(unescape("%3Cscript src='" + gaJsHost + "google-analytics.com/ga.js' type='text/javascript'%3E%3C/script%3E"));


    </script>


    <script type="text/javascript">


      try {


        var pageTracker = _gat._getTracker("'.$id.'");


        pageTracker._trackPageview();


      } catch(err) {}


    </script>';


  }


}





?>


which let me do :



<?php


echo CGoogleAnalytics::tracker('UA-XXXXXX-X'); 


?>


In my layout to display analytics tracker.

Two suggestions crossed my mind.

  • The class prefix is something that should be reserved for Yii classes. There’s nothing wrong with the class name you used, it’s only a recommended convention.

  • The closing php tag should be omitted. It is always better to be prepared.

Anyhow, I feel that this solution is a bit too complicated. But apparently it works. ;)

I have hesitate for the class name as C could also mean "Class" which is not specific to Yii ?

The example isn't good but the helper idea can be reused for many other case where you need to print same big HTML pattern at many place.

I’m curious for this post too and I’d like to see a better solution for this.

If it can’t be done in a “Yii way”. So I think a good old php function would be better.

function gaOutput($string)

{

return 'javascript here';

}

A simple widget seems to me a better solution.




<?php $this->widget('gaTracker', array('param'=>'UA-XXXXXX-X') ); ?>



I would prefer this, too.




<?php $this->widget('application.extensions.widgets.gaTracker', array('param'=>'UA-XXXXXX-X') ); ?>



Take a look at the portlets created in the blog demo.

You may not need the Porlet class demonstrated there – instead just inheriting from CWidget – but that will give you a lot of functionality that you might choose to use.

I would say “the Yii way” in this case is to create a widget. There’s tons of things you can add to your tracking component later on so it’s a good thing to have it in a place where you can extend it.

Here’s a very simple, straight forward example with what you seem to want:

  1. Add your tracking code to "config/params.php"

  2. Create the Google Analytics widget (components/GoogleAnalytics.php):




<?php

class GoogleAnalytics extends CWidget {

  public function run() {

    $this->render('tracking', array('id' => Yii::app()->params['google.analytics']);

  }

}

?>



  1. Add the javascript into it’s view (components/views/tracking.php):



<script type="text/javascript">

var gaJsHost = (("https:" == document.location.protocol) ? "https://ssl." : "http://www.");

document.write(unescape("%3Cscript src='" + gaJsHost + "google-analytics.com/ga.js' type='text/javascript'%3E%3C/script%3E"));

</script>

<script type="text/javascript">

try {

  var pageTracker = _gat._getTracker("'.<?php echo $id ?>.'");

  pageTracker._trackPageview();

} catch(err) {}

</script>



  1. Finally put the widget into your layout right before </body> (protected/views/layouts/main.php):



<?php $this->widget('GoogleAnalytics') ?>



Perfecto!