We just finished a great SugarCon event in San Francisco, and the engineering team really did a great job conveying a lot of tips and tricks to the community. We wanted to continue this momentum, and after discussing the idea with a few developers we have decided to release a new tip/trick every week up to next year’s SugarCon. That’s 52 tips and tricks a year for those of you doing the math. As some of you may note SugarCon was actually 2 weeks ago, so we are already a week behind. Don’t fret, we’ll be releasing 2 tips and tricks this week.
Creating A YouTube Field
Sugar ships with several types of fields out-of-the-box including but not limited to – text, iframe, phone, link, enum …, but every now and then you want to have a new field type. In this article, we shall describe how to create a field for displaying YouTube© videos.
To begin with, let’s review the code that drives field behavior. If you look into the base SugarField directory (include/SugarFields/Fields/Base), you will see the following files
- DetailView.tpl
- EditView.tpl
- SearchForm.tpl
- SugarFieldBase.php
The SugarFieldBase class defined in SugarFieldBase.php handles the processing of the SugarField and loads the appropriate Smarty template (.tpl) file for rendering the field.
Now if you open up any of the .tpl files you will notice that we use the double curly braces (e.g. {{ and }} ) instead of standard Smarty template syntax which uses single curly braces (e.g. { and } ). This is because the Smarty code these templates will create is based upon resolving EditView.tpl or DetailView.tpl with the metadata defined in editviewdefs.php and detailviewdefs.php respectively. For example the base DetailView.tpl code looks like the following:
{{sugarvar key='value'}}
{{if !empty($displayParams.enableConnectors)}}
{{sugarvar_connector view='DetailView'}}
{{/if}}
However, the runtime code that this would generate for the Accounts module (cache/modules/Accounts/DetailView.tpl) looks like:
{$fields.employees.value}
If we wanted to get the value of a field that is different from the one currently being rendered we could do the following:
{{sugarvar memberName='name' key='value'}}
And this would generate the following smarty code
{$fields.name.value}
The reason for the double curly brace ( {{ ) versus the single curly brace ( { ) is that this approach allows us to put a certain level of logic in the code so you could do something like changing the color of the text based on the value of a field:
{if {{sugarvar memberName='employees' key='value' stringFormat='false'}}>1000}
<span style='color:green'>
{else}
<span style='color:purple'>
{/if}
{{sugarvar memberName='employees' key='value'}}</span>
This is rendered at runtime as:
{if $fields.employees.value > 1000}
<span style='color:green'>
{else}
<span style='color:purple'>
{/if}
{$fields.employees.value}</span>
One of the nice things about SugarFields is that they can inherit from parent fields – this is true for both the rendering class and the templates. Even better yet if there is no custom code that needs to be added to our rendering class, the base class can handle the rendering for us and we don’t even need to subclass it. For our YouTube example we will just need to create a custom DetailView.tpl
Step 1: Create the Sugar Field Directory
Create the directory: include/SugarFields/Fields/YouTube
We could actually use the YouTube field in the code right now, but it would render using the base SugarField which is just a text input box.
Step 2: Create DetailView.tpl
Create the File: include/SugarFields/Fields/YouTube/DetailView.tpl
Step 3: Edit DetailView.tpl
I went over to YouTube and grabbed the embed code that is displayed next to one of my favorite videos. We will be expecting users to enter in a YouTube video id in the edit view and based on that id we will render the appropriate video.
<object width="425" height="344">
<param name="movie"
value="http://www.youtube.com/v/{{sugarvar key='value'}}">
</param>
<param name="allowFullScreen" value="true">
</param>
<param name="allowscriptaccess" value="always">
</param>
<embed
src="http://www.youtube.com/v/{{sugarvar key='value'}}"
type="application/x-shockwave-flash"
allowscriptaccess="always" allowfullscreen="true" width="425"
height="344">
</embed>
</object>
Step 4: Using the YouTube Field
There are two ways that the YouTube field may be used, first you may specify a specifc field in the detailviewdefs.php of a module with type set to ‘YouTube’ for example in Accounts you can change website to be a YouTube video field:
array('name'=>'website', 'type'=>'YouTube')
The other way is in the vardefs where you need to set two parameters of a fields vardefs, type and dbType.
'website' =>array (
'name' => 'website',
'vname' => 'LBL_WEBSITE',
'type'=>'YouTube',
'dbType' =>'varchar'
),
Step 5: Don’t Render YouTube Fields That Don’t Have IDs
{if !empty({{sugarvar key='value' stringFormat=false}})}
<object width="425" height="344">
<param name="movie"
value="http://www.youtube.com/v/{{sugarvar key='value'}}">
</param>
<param name="allowFullScreen" value="true">
</param>
<param name="allowscriptaccess" value="always">
</param>
<embed
src="http://www.youtube.com/v/{{sugarvar key='value'}}"
type="application/x-shockwave-flash"
allowscriptaccess="always" allowfullscreen="true" width="425"
height="344">
</embed>
</object>
{else}
No YouTube Video Available
{/if}
Now you have a fully functioning “Custom SugarField”. Stay tuned for this week’s 2nd tip on how to add your new SugarField to Studio.
Note: As of the writing of this article, Sugar 5.2.0a is the current patch version generally available. In the upcoming Sugar 5.2.0c patch, you will be able to place the SugarField files in the custom directory (custom/include/SugarFields/Fields/) in order to override the default behavior in an upgrade-safe manner. However, it is okay to place these changes in the include/SugarFields/Fields/ for this exercise as long as your field names don’t conflict with default field names.