Go Back   vb.org Archive > vBulletin 4 Discussion > vB4 Programming Discussions
  #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
  #2  
Old 01-27-2010, 12:12 AM
Wordplay Wordplay is offline
 
Join Date: Nov 2001
Location: Dengoku
Posts: 864
Благодарил(а): 0 раз(а)
Поблагодарили: 0 раз(а) в 0 сообщениях
Default

very interesting. thanks for the share.
Reply With Quote
  #3  
Old 06-24-2010, 01:51 PM
arvid arvid is offline
 
Join Date: May 2003
Location: Stockholm, Sweden
Posts: 13
Благодарил(а): 0 раз(а)
Поблагодарили: 0 раз(а) в 0 сообщениях
Default

Great guide!
Reply With Quote
Reply

Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump


All times are GMT. The time now is 06:42 PM.


Powered by vBulletin® Version 3.8.12 by vBS
Copyright ©2000 - 2024, vBulletin Solutions Inc.
X vBulletin 3.8.12 by vBS Debug Information
  • Page Generation 0.03995 seconds
  • Memory Usage 2,272KB
  • Queries Executed 13 (?)
More Information
Template Usage:
  • (1)SHOWTHREAD
  • (1)ad_footer_end
  • (1)ad_footer_start
  • (1)ad_header_end
  • (1)ad_header_logo
  • (1)ad_navbar_below
  • (1)ad_showthread_beforeqr
  • (1)ad_showthread_firstpost
  • (1)ad_showthread_firstpost_sig
  • (1)ad_showthread_firstpost_start
  • (2)bbcode_html
  • (3)bbcode_php
  • (1)footer
  • (1)forumjump
  • (1)forumrules
  • (1)gobutton
  • (1)header
  • (1)headinclude
  • (1)navbar
  • (3)navbar_link
  • (120)option
  • (3)post_thanks_box
  • (3)post_thanks_button
  • (1)post_thanks_javascript
  • (1)post_thanks_navbar_search
  • (3)post_thanks_postbit_info
  • (3)postbit
  • (3)postbit_onlinestatus
  • (3)postbit_wrapper
  • (1)spacer_close
  • (1)spacer_open
  • (1)tagbit_wrapper 

Phrase Groups Available:
  • global
  • inlinemod
  • postbit
  • posting
  • reputationlevel
  • showthread
Included Files:
  • ./showthread.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
  • showthread_start
  • showthread_getinfo
  • forumjump
  • showthread_post_start
  • showthread_query_postids
  • showthread_query
  • bbcode_fetch_tags
  • bbcode_create
  • showthread_postbit_create
  • postbit_factory
  • 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
  • tag_fetchbit_complete
  • forumrules
  • navbits
  • navbits_complete
  • showthread_complete