Recent Topics

1 May 25, 2017 08:25    

Is there an easy way to get all the container names ( $sco_name ) that are being displayed on the active page?
Perhaps something like $Skin->get_containers() but instead of all the skin containers only the containers on the current page?

Perhaps a global variable such as $disp_containers that has an array of containers rendered on $disp?

2 May 27, 2017 11:37

@achillis it's difficult to know what containers are actually available-displayed because of the sequential logic of the skins, so the skin_container() calls are made one by one in the template file and its sub-templates, so the real track of all of them can be done only at the very last line of the main template file.

Something that may work is to open the template file and look for all the skin_container() calls, just as it's done over all the skin's files when we install the skin (or click on the "Reload containers" button of the widgets screen).

The code might be something like this:

function get_current_containers()
    {
        global $disp_handler;
        global $Messages;

        $file_contents = @file_get_contents( $disp_handler );

        if( ! is_string( $file_contents ) )
        { // Cannot get contents:
            $Messages->add_to_group( sprintf( T_('Cannot read skin file «%s»!'), $disp_handler ), 'error', T_('File read error:') );
            return;
        }

        // DETECT if the file contains containers:
        if( ! preg_match_all( '~ (\$Skin->|skin_)container\( .*? ((\' (.+?) \')|(" (.+?) ")) ~xmi', $file_contents, $matches ) )
        { // No containers in this file, go to next:
            return;
        }

        // Merge matches from the two regexp parts (due to regexp "|" )
        $current_containers_list = array_merge( $matches[4], $matches[6] );

        foreach( $current_containers_list as $container )
        {
            if( empty( $container ) )
            { // regexp empty match -- NOT a container:
                continue;
            }

            if( in_array( $container, $current_containers_list ) )
            { // we already have that one
                continue;
            }

            $current_containers_list[] = $container;
        }

        return array_filter($current_containers_list, function($value) { return $value !== ''; });
    }

If you include it in the _skin.class.php file of your skin, you may access $Skin->get_current_containers() anywhere in your template files, or even $this->get_current_containers() in the same class.

As said, the downside of this is that you miss any container that might be defined in sub-templates. Also, you only get an array of the containers that might be displayed, but not if they are actually being displayed.

If you explain us a bit more of what are you trying to do, maybe we can offer you a more polished option.

3 May 27, 2017 14:16

When one activates the dev menu conf/_advanced.php //$dev_menu = 1; and &display_containers=show then it displays only the containers being displayed (not all within a skin). If this can somehow be used on a global or function call it would do what I need.

I designed a 'One Page' skin template (@see https://blackrockdigital.github.io/startbootstrap-agency/ ) which basically makes use of the $dsip = 'front' method and containers (Front Page Main Area / Front Page Secondary Area).

To add a contact section with a contact form I created a contact plugin ( Similar to contact widget in b2e 7.0 ). Now it presented some challenges, namely that if one clicks on a 'user contact' link the user is redirected to the $disp='msgform' where I would like for the user to remain on the `$disp='front' contact form.

Also, when the form is loaded it needs to make use of a contact form template _contact_msg_form.php specified by the plugin (not the skin) also the Ajax enabled form needs to load the same form specified by the plugin.

So the contact plugin uses its own files message_send.php and _contact_msg.form.php. if I want to make use of the core Ajax function then I need to be able to tell Ajax to use the plugin's template path, not it's own.

Currently I have to hack the htsrv/anon_async.php file and raplace:

require skin_template_path( '_contact_msg.form.php' );

with

		$template_path = param( 'template_path', 'string', '' );
		
		if( file_exists( $template_path) )
		{ // Template file exists for the current form
			require $template_path;
		}
		else {

		require skin_template_path( '_contact_msg.form.php' );

		}

@See http://forums.b2evolution.net/requesting-new-core-widget

Now I created a plugin based on the organization members which displays a contact link (with social links) for each member (see screenshot), and this is where the tricky part comes in. If the organization members plugin and the 'contact plugin' are both rendered/displayed on the same page (being displayed) then the contact link will have this function:

$form_url = isset($Blog) ? $Blog->get('msgformurl') : $Blog->get('url');

$found_contact_widget = ( ! empty($params['widget_code']) ) $this->found_contact_widget( $params['widget_code'] ) : false;

$form_url = ( $found_contact_widget ) ? $this->msgform_link : $form_url;

echo $org_User->msgform_link( $form_url,'','',$text,'','');

This will populate the msgform displayed by the plugin ($disp='front') and NOT redirect to ($disp = 'msgform').

in order for the variable $found_contact_widget to be true it will need something like this:

	function found_contact_widget( $widget_code )
	{   
			// get all the containers displayed on the active page, so this is an array
			global $disp_containers;

			// Active Blog
			global $Blog;

			$EnabledWidgetCache = & get_EnabledWidgetCache();

			foreach( $disp_containers as $container )
			{

			   $Widget_array = & $EnabledWidgetCache->get_by_coll_container( $Blog->ID, $container );

				if( ! empty( $Widget_array ) )
				{
					foreach( $Widget_array as $Widget )
					{
						// Skip this widget if the code does not match
						if ( $Widget->code != $widget_code ) continue;

						// if we get here we found a match in a container currently displayed/rendered
						return true;

					}
				}
			}

			// we did not find a widget in the currently displayed containers
			return false;
	}

Note: consider this code as theoretical as the there's actually more to it but I am sure this explains the reason 'why'?


Form is loading...