1. This site uses cookies. By continuing to use this site, you are agreeing to our use of cookies. Learn More.

Admin Template "<xen:option ..." in TemplateHook

Discussion in 'XenForo Development Discussions' started by r1pe, May 16, 2013.

  1. r1pe

    r1pe Member

    Hello,

    I have a question regarding the template function "<xen: option ... " in the "forum_edit" admin template file. I want to extend the "Forum Options" tab. XenForo use the template function "<xen: option ..." to build an option field in this template.

    Code:
                    <xen:option name="allow_posting" label="{xen:phrase allow_new_messages_to_be_posted_in_this_forum}" selected="{$forum.allow_posting}">
                        <xen:hint>{xen:phrase if_disabled_users_not_able_post_messages_in_forum}</xen:hint>
                    </xen:option>    
    How can I build an option field in a TemplateHook file? Sure, I could use normal HTML but I think there is a better solution.

    Thanks in advance.
     
  2. Chris D

    Chris D XenForo Developer Staff Member

    If you echo out the template hook the existing contents will actually be normal HTML.

    At that point the template has been compiled so it will be too late to use xen tags.

    However from your template hook you can inject a new template using $template->create() that new template can contain xen tags.
     
  3. Lawrence

    Lawrence Well-Known Member

    Here is an example from my site:

    Create your additional forum options template:
    Code:
        <xen:spinboxunit name="xp_mod" value="{$xpModOptions.xp_mod}" step="1" min="0" max="100" label="{xen:phrase iwd_experience_modifier}:">
            <xen:explain>{xen:phrase iwd_experience_modifier_explain}</xen:explain>
        </xen:spinboxunit>
        <xen:spinboxunit name="gold_mod" value="{$xpModOptions.gold_mod}" step="1" min="0" max="100" label="{xen:phrase iwd_gold_percentage}:">
            <xen:explain>{xen:phrase iwd_gold_percentage_explain}</xen:explain>
        </xen:spinboxunit>
        <xen:checkboxunit label="{xen:phrase iwd_iwd_options}:">
            <xen:option name="encounter" label="{xen:phrase iwd_enable_encounters}" selected="{$xpModOptions.encounter}">
                <xen:hint>{xen:phrase iwd_if_disabled_random_encounters_will_be_turned_off}</xen:hint>
            </xen:option>
            <xen:option name="trap" label="{xen:phrase iwd_enable_traps}" selected="{$xpModOptions.trap}">
                <xen:hint>{xen:phrase iwd_if_enabled_random_traps_will_be_turned_on}</xen:hint>
            </xen:option>
            <xen:option name="treasure" label="{xen:phrase iwd_enable_treasure}" selected="{$xpModOptions.treasure}">
                <xen:hint>{xen:phrase iwd_if_enabled_random_treasures_will_be_turned_on}</xen:hint>
            </xen:option>
        </xen:checkboxunit>
    Create a listener for Templates to pre-load and then add in your forum options template:
    Code:
    <?php
     
    class IcewindDaleRP_IcewindDale_Listener_Template
    {
        public static function template_create(&$templateName, array &$params, XenForo_Template_Abstract $template)
        {
            switch ($templateName)
            {
                case 'forum_edit':
                    $template->preloadTemplate('iwd_forum_xp_modifiers');
                break;
            }
        }
       
        public static function template_hook($name, &$contents, array $hookParams, XenForo_Template_Abstract $template)
        {
            switch ($name)
            {
                case 'admin_forum_edit_forum_options':
                    $xpmOptionsModel = XenForo_Model::create('IcewindDaleRP_IcewindDale_Model_Options');
     
                    $params = $template->getParams();
                    if (!empty($params['forum']['node_id']))
                    {
                        $xpModOptions = $xpmOptionsModel->getForumXpModOptions($params['forum']['node_id']);
                    }
                    else
                    {
                        $xpModOptions = $xpmOptionsModel->getForumXpModDefaults();
                    }
     
                    $contents .= $template->create('iwd_forum_xp_modifiers', array(
                        'xpModOptions' => $xpModOptions))->render();
                break;
            }
        }
    }
    Create a loadClassController listener to listen for Xenforo_ControllerAdmin_Forum
    Code:
    <?php
     
    class IcewindDaleRP_IcewindDale_Listener_LoadClassController
    {
            public static function loadClassListener($class, &$extend)
            {
            switch ($class)
            {
                        case 'XenForo_ControllerAdmin_Forum':
                    $extend[] = 'IcewindDaleRP_IcewindDale_ControllerAdmin_Forum';
                break;
                    }
            }
    }
    Create your custom load class controller for above:
    Code:
    <?php
     
    class IcewindDaleRP_IcewindDale_ControllerAdmin_Forum extends XFCP_IcewindDaleRP_IcewindDale_ControllerAdmin_Forum
    {
        public function actionSave()
        {
            $response = parent::actionSave();
            if ($response->redirectType == XenForo_ControllerResponse_Redirect::SUCCESS)
            {
                $xpmData = $this->_input->filter(array(
                    'node_id' => XenForo_Input::UINT,
                    'xp_mod' => XenForo_Input::UINT,
                    'gold_mod' => XenForo_Input::UINT,
                    'encounter' => XenForo_Input::UINT,
                    'trap' => XenForo_Input::UINT,
                    'treasure' => XenForo_Input::UINT
                ));
               
                if (empty($xpmData['node_id']))
                {
                    $xpmData['node_id'] = $this->_getLastSavedForumNodeId();
                }
       
                $dw = XenForo_DataWriter::create('IcewindDaleRP_IcewindDale_DataWriter_Forum');
               
                $xpmOptionsModel = $this->_getForumXpModOptionsModel();
                if ($xpmOptionsModel->verifyForumXpModId($xpmData['node_id']))
                {
                    $dw->setExistingData($xpmData['node_id']);
                }
     
                $dw->bulkSet($xpmData);
                $dw->save();
               
                $xpmOptionsModel->rebuildForumXpModCache();
            }
     
            return $response;
        }
       
        public function actionDelete()
        {
            $parent = parent::actionDelete();
     
            $this->_getForumXpModOptionsModel()->removeDeletedForums();
     
            return $parent;
        }
       
        public function actionValidateField()
        {
            $parentResponse = parent::actionValidateField();
     
            $fieldName = $this->_input->filterSingle('name', XenForo_Input::STRING);
            if ($fieldName == 'xp_mod' OR $fieldName == 'gold_mod')
            {
                $xpmResponse = $this->_validateField('IcewindDaleRP_IcewindDale_DataWriter_Forum', array(
                    'existingDataKey' => $this->_input->filterSingle('node_id', XenForo_Input::UINT)
                ));
     
                return $xpmResponse;
            }
            else
            {
                return $parentResponse;
            }
        }
       
        protected function _getForumXpModOptionsModel()
        {
            return $this->getModelFromCache('IcewindDaleRP_IcewindDale_Model_Options');
        }
       
        protected function _getLastSavedForumNodeId()
        {
            return XenForo_Application::get('db')->fetchOne('
                SELECT node_id
                FROM xf_forum
                ORDER BY node_id
                DESC
            ');
        }
    }
    Create the data writer for your custom forum options:
    Code:
    <?php
     
    class IcewindDaleRP_IcewindDale_DataWriter_Forum extends XenForo_DataWriter
    {
        protected $_existingDataErrorPhrase = 'iwdrp_requested_forum_not_found';
     
        protected function _getFields()
        {
            return array(
                'iwdrp_forum_xp_mods' => array(
                        'node_id' => array('type' => self::TYPE_UINT, 'required' => true),
                        'xp_mod' => array('type' => self::TYPE_UINT, 'required' => true, 'default' => 78),
                        'gold_mod' => array('type' => self::TYPE_UINT, 'required' => true, 'default' => 100),
                        'encounter' => array('type' => self::TYPE_UINT, 'required' => true, 'default' => 1),
                        'trap' => array('type' => self::TYPE_UINT, 'required' => true, 'default' => 0),
                        'treasure' => array('type' => self::TYPE_UINT, 'required' => true, 'default' => 0)
                )
            );
        }
       
        protected function _getExistingData($data)
        {
            if (!$id = $this->_getExistingPrimaryKey($data, 'node_id', 'iwdrp_forum_xp_mods'))
            {
                return false;
            }
     
            return array('iwdrp_forum_xp_mods' => $this->_getForumXpModOptionsModel()->getForumXpModOptions($id));
        }
       
        protected function _getUpdateCondition($tableName)
        {
            return 'node_id = ' . $this->_db->quote($this->getExisting('node_id'));
        }
     
        protected function _postSave()
        {
            $this->_rebuildXPMCache();
        }
     
        protected function _postDelete()
        {
            $this->_rebuildXPMCache();
        }
     
        protected function _rebuildXPMCache()
        {
            $this->_getForumXpModOptionsModel()->rebuildForumXpModCache();
        }
     
        protected function _getForumXpModOptionsModel()
        {
            return $this->getModelFromCache('IcewindDaleRP_IcewindDale_Model_Options');
        }
    }
    and the result is this:
    forumOptionsExample.jpg
     
    r1pe and tyteen4a03 like this.
  4. r1pe

    r1pe Member

    Thanks for your answers. There are basically the same so I use the template->create() function to get what I want. Special thanks to "Lawrence" for the detailed answer.
     

Share This Page