View Single Post
  #1  
Old 01-26-2010, 05:53 PM
ddrake ddrake is offline
 
Join Date: Jan 2010
Posts: 16
Благодарил(а): 0 раз(а)
Поблагодарили: 0 раз(а) в 0 сообщениях
Default How to: Custom Widget Type

I've been working on a site that is hosting a fairly large number of flash videos. I've been using static html widgets and pasting in the html to display the flash player/video for each. Each flash video consists of its own directory containing four files (a .swf, an .mp4, a .png and a .js).

It works, but there are two problems:
  1. The html has to be edited for each widget to set the correct path and file name which is time-consuming and error-prone
  2. If the format (e.g. the size, etc..) of the videos were to change, all the widgets would have to be edited.

To get around this, I created a custom widget type that has two configuration variables: a path and a swf filename. The widget code generates html from these two parameters and displays it. I would like to package this as a mod, but I don't know how to do that yet. Maybe someone could give me some pointers...?

This article: http://www.vbulletin.com/forum/entry...page3#comments is a bit out of date, but gave me a starting place.

Here are essentially the steps I used.

Database
PHP Code:
Insert Into product(titledescriptionversionactiveurlversioncheckurl)
values ('amutil''Agedman Utilities''Agedman Custom Widget Types''1.0'1'''');
Insert into package(productid, class)
values ('amutil''AmUtil');
Insert into cms_widgettype(class, packageid)
values ('AmFlash'last_insert_id()); 
AdminCp
Add a new phrase with
type: 'CMS Widget Types'
product: 'Agedman Utilities'
varname: 'widgettype_amutil_amflash'
text: 'Standard Flash Video'

Create two templates (modified versions of the ones used by the static html widget type):
1. Display template for displaying the widget in a section (this is actually an exact copy of the one for the static html widget type).
title: amutil_widget_amflash_page
template:

HTML Code:
<div class="cms_widget">
	<div class="block">
		<div class="cms_widget_header">
		<h3>{vb:raw widget_title}</h3>
		</div>
		<div class="cms_widget_content">
		{vb:raw static_html}
		</div>
	</div>
</div>
2. Configuration template for editing the widget (modified -- removed 'statichtml' field, added 'path' and 'filename' fields.
title: amutil_widget_amflash_config
template:
HTML Code:
<div id="overlay1" style="height:190px;width:400px">
	<div class="cms_widget_config">
		<div class="fullwidth">
			<label for="path" class="label">Path w/o Final Separator:</label>
			<textarea name="path" id="path" cols="50" rows="2">{vb:raw path}</textarea>
			<label for="filename" class="label">SWF Filename w/ suffix:</label>
			<textarea name="filename" id="filename" cols="50" rows="2">{vb:raw filename}</textarea>
		</div>
		<div class="fullwidth">
			<label for="template_name" class="label">{vb:rawphrase template_name}</label>
			<input class="button" name="template_name" id="template_name" size="40" value="{vb:raw template_name}" tabindex="1" />
		</div>
		<input type="hidden" name="do" value="config" />
		<input type="hidden" name="item_type" value="{vb:raw item_type}" />
		<input type="hidden" name="item_class" value="{vb:raw item_class}" />
		<input type="hidden" name="item_id" value="{vb:raw item_id}" />
		<input type="hidden" name="s" value="{vb:raw session.sessionhash}" />
		<input type="hidden" name="securitytoken" value="{vb:raw bbuserinfo.securitytoken}" />
	</div>
</div>
File System
Make directories: /packages/amutil/widget/ and /packages/amutil/item/widget/

Copy class definition file (use the static html widget code as a starting place)
cp /packages/vbcms/item/widget/static.php /packages/amutil/item/widget/amflash.php

Copy main class file (use the static html widget code as a starting place)
cp /packages/vbcms/widget/static.php /packages/amutil/widget/amflash.php

Edited Item Class File (most original comments removed)
PHP Code:
// Modified this line to add the package and class names
class AmUtil_Item_Widget_AmFlash extends vBCms_Item_Widget
{
    
// Modified this line with my class name
    
protected $class 'AmFlash';

        
// added 'path' and 'filename' fields.  Note: we need to keep the 'statichtml' field, here or nothing will display on the page...
    
protected $config = array('statichtml' =>'','path' => 'Enter Path here...','filename' => 'Enter Filename here...''template_name' => 'amutil_widget_amflash_page');

Edited Main Class File (most original comments removed)
PHP Code:

// Modified this line to add the package and class names
class AmUtil_Widget_AmFlash extends vBCms_Widget
{
    
// Modified this line with my package name
    
protected $package 'AmUtil';

        
// Modified this with my class name
    
protected $class 'AmFlash';

    protected 
$canconfig false;

     
// Returns the configuration view for the widget.
    
public function getConfigView()
    {
        
$this->assertWidget();

        
// 'do' and 'template_name' should be included; add any additional input fields you may need to this array
        // For this widget type, I added 'path' and 'filename' 
                // statichtml still needs to be there for the widget to update correctly
        
vB::$vbulletin->input->clean_array_gpc('r', array(
            
'do'      => vB_Input::TYPE_STR,
            
'path'    => vB_Input::TYPE_STR,
            
'filename'    => vB_Input::TYPE_STR,
            
'statichtml'    => vB_Input::TYPE_STR,
            
'template_name'    => vB_Input::TYPE_STR
        
));

        
$view = new vB_View_AJAXHTML('cms_widget_config');
        
$view->title = new vB_Phrase('vbcms''configuring_widget_x'$this->widget->getTitle());
        
$config $this->widget->getConfig();

        
// This ugly html is the same for all the Flash videos on the site.  Just hard-coded here...
        
$sample_html '            <div id="media" style="margin-left: 20px;">
            <object id="csSWF" classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" width="640" height="498" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=9,0,115,0">
                <param name="src" value="YOUR_PATH/YOUR_FILENAME"/>
                <param name="bgcolor" value="#1a1a1a"/>
                <param name="quality" value="best"/>
                <param name="allowScriptAccess" value="always"/>
                <param name="allowFullScreen" value="true"/>
                <param name="scale" value="showall"/>
                <param name="flashVars" value="autostart=false"/>
                <embed name="csSWF" src="YOUR_PATH/YOUR_FILENAME" width="640" height="498" bgcolor="#1a1a1a" quality="best" allowScriptAccess="always" allowFullScreen="true" scale="showall" flashVars="autostart=false&thumb=YOUR_PATH/FirstFrame.png&thumbscale=45&color=0x000000,0x000000" pluginspage="http://www.macromedia.com/shockwave/download/index.cgi?P1_Prod_Version=ShockwaveFlash"></embed>
            </object>
        </div>'
;

        if ((
vB::$vbulletin->GPC['do'] == 'config') AND $this->verifyPostId())
        {
            
// get the posted data from the ajax form into the $config array, constructing statichtml from the data
            
$config['path'] = str_replace('%u0025''%' vB::$vbulletin->GPC['path']);
            
$config['filename'] = str_replace('%''%' vB::$vbulletin->GPC['filename']);
                        
// construct the html from the sample html, the path and the swf filename
            
$config['statichtml'] = str_replace('YOUR_FILENAME'$config['filename'], str_replace('YOUR_PATH'$config['path'] ,$sample_html));

            
$widgetdm $this->widget->getDM();

            if (
$this->content)
            {
                
$widgetdm->setConfigNode($this->content->getNodeId());
            }
            if (
vB::$vbulletin->GPC_exists['template_name'])
            {
                
$config['template_name'] = vB::$vbulletin->GPC['template_name'];
            }
            
$widgetdm->set('config'$config);

            
// try to save to the database
            
$widgetdm->save();

            if (!
$widgetdm->hasErrors())
            {
                if (
$this->content)
                {
                    
$segments = array('node' => $this->content->getNodeURLSegment(),
                                        
'action' => vB_Router::getUserAction('vBCms_Controller_Content''EditPage'));
                    
$view->setUrl(vB_View_AJAXHTML::URL_FINISHEDvBCms_Route_Content::getURL($segments));
                }

                
$view->setStatus(vB_View_AJAXHTML::STATUS_FINISHED, new vB_Phrase('vbcms''configuration_saved'));
            }
            else
            {
                if (
vB::$vbulletin->debug)
                {
                    
$view->addErrors($widgetdm->getErrors());
                }

                
// only send a message
                
$view->setStatus(vB_View_AJAXHTML::STATUS_MESSAGE, new vB_Phrase('vbcms''configuration_failed'));
            }
        }
        else
        {
            
// create a configuration view object
            
$configview $this->createView('config');

            if (!isset(
$config['template_name']) OR ($config['template_name'] == '') )
            {
                
$config['template_name'] = 'amutil_widget_amflash_page';
            }
            
// add the config content
            
$configview->template_name $config['template_name'];

            
// the current data to be populated on the configuration form
            
$configview->path $config['path'] ? htmlspecialchars_uni($config['path']) : '';
            
$configview->filename $config['filename'] ? htmlspecialchars_uni($config['filename']) : '';

            
// item id to ensure form is submitted to us
            
$this->addPostId($configview);

            
$view->setContent($configview);

            
// send the view
            
$view->setStatus(vB_View_AJAXHTML::STATUS_VIEW, new vB_Phrase('vbcms''configuring_widget'));
        }

        return 
$view;
    }

       
// Fetches the standard page view for a widget.
    
public function getPageView()
    {
        
$this->assertWidget();

        
$config $this->widget->getConfig();
        if (!isset(
$config['template_name']) OR ($config['template_name'] == '') )
        {
            
$config['template_name'] = 'amutil_widget_amflash_page';
        }

        
// Create view and set variables -- this is where the flash video player gets rendered on the page
        
$view = new vBCms_View_Widget($config['template_name']);
        
$view->class $this->widget->getClass();
        
$view->title $view->widget_title $this->widget->getTitle();
        
$view->description $this->widget->getDescription();
        
$view->static_html $config['statichtml'];

        return 
$view;
    }

Note: you may need to clear the CMS Cache before you will see the new Widget Type show up in the drop-down list -- I did.
Reply With Quote
 
X vBulletin 3.8.12 by vBS Debug Information
  • Page Generation 0.01232 seconds
  • Memory Usage 1,930KB
  • Queries Executed 11 (?)
More Information
Template Usage:
  • (1)SHOWTHREAD_SHOWPOST
  • (1)ad_footer_end
  • (1)ad_footer_start
  • (1)ad_header_end
  • (1)ad_header_logo
  • (1)ad_navbar_below
  • (2)bbcode_html
  • (3)bbcode_php
  • (1)footer
  • (1)gobutton
  • (1)header
  • (1)headinclude
  • (6)option
  • (1)post_thanks_box
  • (1)post_thanks_button
  • (1)post_thanks_javascript
  • (1)post_thanks_navbar_search
  • (1)post_thanks_postbit_info
  • (1)postbit
  • (1)postbit_onlinestatus
  • (1)postbit_wrapper
  • (1)spacer_close
  • (1)spacer_open 

Phrase Groups Available:
  • global
  • postbit
  • reputationlevel
  • showthread
Included Files:
  • ./showpost.php
  • ./global.php
  • ./includes/init.php
  • ./includes/class_core.php
  • ./includes/config.php
  • ./includes/functions.php
  • ./includes/class_hook.php
  • ./includes/modsystem_functions.php
  • ./includes/functions_bigthree.php
  • ./includes/class_postbit.php
  • ./includes/class_bbcode.php
  • ./includes/functions_reputation.php
  • ./includes/functions_post_thanks.php 

Hooks Called:
  • init_startup
  • init_startup_session_setup_start
  • init_startup_session_setup_complete
  • cache_permissions
  • fetch_postinfo_query
  • fetch_postinfo
  • fetch_threadinfo_query
  • fetch_threadinfo
  • fetch_foruminfo
  • style_fetch
  • cache_templates
  • global_start
  • parse_templates
  • global_setup_complete
  • showpost_start
  • bbcode_fetch_tags
  • bbcode_create
  • postbit_factory
  • showpost_post
  • postbit_display_start
  • post_thanks_function_post_thanks_off_start
  • post_thanks_function_post_thanks_off_end
  • post_thanks_function_fetch_thanks_start
  • post_thanks_function_fetch_thanks_end
  • post_thanks_function_thanked_already_start
  • post_thanks_function_thanked_already_end
  • fetch_musername
  • postbit_imicons
  • bbcode_parse_start
  • bbcode_parse_complete_precache
  • bbcode_parse_complete
  • postbit_display_complete
  • post_thanks_function_can_thank_this_post_start
  • showpost_complete