Atlantic Business Technologies, Inc.

Category: Managed Services

  • WordPress – Promote a Post in a Widget

    Here’s a WordPress plugin that will allow you to feature a single item in a widget, until you tell it to automatically expire.

    As taken from the readme file:


    Description

    Simple widget to display (promote) a specific post/page. Provides a list of from all public post types to choose an entry to promote until a specified date. When this “promotion” expires, you can either display a static message or use another post/page instead.


    Installation

    1. Upload the plugin folder to your plugins directory /content/plugins/ directory
    2. Activate the plugin through the ‘Plugins’ menu in WordPress
    3. Add the Widget “Promoted Content” to a sidebar

    Frequently Asked Questions

    What are the options?

    • Title: The displayed widget title – leaving it blank will use the post title (if you override the default, see Hooks)
    • Feature Expires: until what date (YYYY-MM-DD) to show the promoted post; after which fall back to the default
    • Feature Post: choose from the dropdown of public post types to promote
    • Default: display this entry instead after the expiration
    • Trim summary to: if no excerpt is provided, shorten the post content to this number of words

    Note that you can select the most recent post from the dropdown options.

    How can I change the defaults?

    If you don’t specify certain options, the widget will use builtin defaults. Override these with the following hook:
    [php]
    add_filter(‘abt_promo_post_defaults’, ‘YOUR_HOOK’);
    [/php]

    where YOUR_HOOK is a function that takes an array and returns the following settings:

    [php]
    function promo_widget_defaults($settings){
    return array(
    #’title’ => ‘Latest From MY SITE’, // disable to use post title
    ‘display’ => ‘Check out our new video! Credit goes to … <p><a class=”archive” href=”/category/news”>News Archive</a></p>’,
    ‘url’ => ‘#’,
    ‘image’ => ‘<img src=”‘ . get_stylesheet_directory_uri() . ‘/images/g_video.jpg” alt=”Latest from MY SITE”>’,
    );
    }
    [/php]

    What else can I use?

    Two static methods are available for “embedding” the widget in code – basically just the internal processing used by the widget function.

    abtcore_feature_widget::display_promo($args, $before_title, $after_title) 

    which uses the following

    abtcore_feature_widget::get_promo($args) 

    to get either the promoted post or the default. $args will contain an array of the widget options (title, expire, promo, default, trim).

    Function get_promo will return an array of (title, display, url, and image) to display_promo where it gets combined with the defaults from the hook to output the widget HTML.

  • How to Get a List of your Drupal Modules

    Has a client ever asked you “So what Drupal modules are we using?” With this step-by-step guide, you can now generate a list in a nice table of all of the Drupal modules a website is actively using. This jQuery snippet will help you to generate a table with links to the project page for each Drupal module.Ā  Sign up here to receive more great tips delivered straight to your inbox, like this Drupal Module list generator.

    1. Go to http://yoursite.com/admin/modules
    2. Run the following javascript in your Console (Firebug, Developer Tools, etc – F12)

    [js]
    (function($, D, boxid){ /*–start–*/var $checkboxes = $(‘:checkbox’)
    , $checked = $checkboxes.filter(‘:checked’)
    , $dom_render_to_div = false
    ;
    console.log($checked.length, ‘enabled modules’);

    // clear old version
    $(‘#’+boxid).remove();

    var render = function(o, renderfn){
    renderfn(o);
    };
    var render_to_console = function(o){
    console.log(o.i, ‘Section:’ + o.s, ‘Module:’ + o.l, o.v);
    };
    var render_to_div = function(r){
    if( false === $dom_render_to_div ){
    var $container = $(‘<div id=”‘ + boxid + ‘” class=”debug”><h3>Active Modules</h3></div>’);
    $container.append(‘<table></table>’).append(‘<div class=”clearfix”>Copy Above</div>’);
    $container.css({
    ‘background-color’: ‘#FFFFFF’
    , ‘left’: ‘20%’
    , ‘padding’: ‘5%’
    , ‘position’: ‘absolute’
    , ‘top’: ‘20%’
    });

    $(‘body’).append($container);
    $dom_render_to_div = $container.find(‘table’);
    $dom_render_to_div.append(‘<tr><th>i</th><th>Section</th><th>Label</th><th>Version</th></tr>’);
    }
    $dom_render_to_div.append(‘<tr><td>’ + r.i + ‘</td><td>’ + r.s + ‘</td><td><a href=”https://drupal.org/project/’ + r.id + ‘”>’ + r.l + ‘</a></td><td>’ + r.v + ‘</td></tr>’);
    };

    $checked.each(function(i,o){
    var $o = $(o);
    var $row = $o.parents(‘tr’);
    var section = $o.parents(‘fieldset’).find(‘legend’).text();
    if( 7 == D ) section = section.replace(/Hide /i, ”);
    var label = “” + $row.find(‘td:nth(1) label’).text();
    var version = $row.find( 7 == D ?’td:nth(2)’ : ‘td.version’ ).text();
    var iden = $row.find(‘:checkbox’).attr(‘name’).match(/][([^]]+)]/)[1];

    var row = {“i”: i, “s”: section, “l”: label, “v”: version, “id”: iden};

    render(row, render_to_div);
    });
    /*–end–*/ })(jQuery, 7, ‘module-list-debug’);
    [/js]

  • The “Complete” How-to Set Up XAMPP on Windows

    If you run PHP locally on a Windows machine, you’re probably using XAMPP.  By default, you put all your files in the xampp directory (htdocs) to make things work.  However, if want a different directory structure (i.e. under “My Documents”) you can set up domain or subdirectory aliases.

    The following steps are the mostly-complete guide to setting up XAMPP: set alternate folders/domains/subdirectories, enable “missing” extensions, and let it play nicely with VisualStudio’s local IIS.

    1. Download zip version
    2. run setup_xampp.bat to fix directories
    3. to access your local dev like `http://ALIAS.localhost:81/whatever.php`, in apacheconfextrahttpd-vhosts.conf add your custom directories like: (note port 81 from step 7)
      [php htmlscript=”true”]

      <VirtualHost *:81>
      ServerAdmin YOUR@EMAIL.COM
      DocumentRoot “/Relative/Path/To/LocalFiles”
      ServerName ALIAS.localhost
      ServerAlias www.ALIAS.localhost
      ErrorLog “logs/ALIAS.localhost-error.log”
      CustomLog “logs/ALIAS.localhost-access.log” combined

      <Directory “/Relative/Path/To/LocalFiles”>
      Options Indexes FollowSymLinks
      AllowOverride All
      Order allow,deny
      Allow from all
      </Directory>
      </VirtualHost>
      [/php]

       

    4. Update your hosts file (C:WindowsSystem32driversetchosts) accordingly: 127.0.0.1 ALIAS.localhost
      (added bonus: wildcards in hosts file (untested))
    5. OR, instead of #3 and #4, configure subdirectory aliases in xamppapacheconfextrahttpd-userdir.conf, which will let you access your local dev like `http://localhost/ALIAS/whatever.php`
      [php htmlscript=”true”]
      <IfModule alias_module>
      # ===== Description of the following
      Alias /ALIAS “/Relative/Path/To/LocalFiles”
      # Access control, etc
      <Directory “/Relative/Path/To/LocalFiles”>
      AllowOverride All
      Options Indexes FollowSymLinks
      Order allow,deny
      Allow from all
      </Directory>
      </IfModule>
      [/php]
    6. Allow “missing” extensions by uncommenting dll line in xamppphpphp.ini
    7. If also have IIS (VisualStudio) on same computer, you’ll need to change the ports (you can use other numbers)
      1. in xamppapacheconfhttpd.conf — change `Listen *:80` to `Listen: *.81`, `ServerName localhost:80` to `ServerName localhost:81`
      2. in xamppapacheconfextrahttpd-ssl.conf — change `Listen 443` to `Listen 442`
      3. ignore the message in xampp-control that says it started on port 80 (that’s hardcoded)
  • WordPress Debugging – “Doing It Wrong” warnings

    WordPress recently added some “helpful” error messages warning you when you’re not doing certain things correctly. Specifically, adding scripts and/or styles incorrectly using the wp_enqueue_* function.

    However, even though it appears they tell you where things went wrong (via trigger_error), it actually just points you to the _doing_it_wrong function.

    Fortunately, those hook-crazy developers threw us a bone in that function:
    [php]
    do_action( ‘doing_it_wrong_run’, $function, $message, $version );
    //
    [/php]

    Now we can figure out the offender ourselves with a hook:
    [php highlight=”13″]
    /**
    * Because new WP 3.3 “doing it wrong” warnings don’t really tell you where you screwed up…
    * @param string $function The function that was called.
    * @param string $message A message explaining what has been done incorrectly.
    * @param string $version The version of WordPress where the message was added.
    */
    function abt_doing_it_wrong_helper($function, $message, $version){
    $before = <<<EOD
    <strong>$function:</strong> v$version
    EOD;
    debug_whereat(3, 5, $before);
    }
    add_action( ‘doing_it_wrong_run’, ‘abt_doing_it_wrong_helper’, 10, 3 );
    //
    [/php]

    And the helper function for printing debug_backtrace (use your own flavor):
    [php]
    /**
    * Pretty-print debug_backtrace()
    * @param int $limit {optional} when to stop printing – how many recursions up/down
    * @param int $skip {optional} when to start printing – how many calls to skip over
    * @param string $before {optional} extra html to print before the table, inside debug container
    * @param string $after {optional} extra html to print before the table, inside debug container
    * */
    function debug_whereat($limit = false, $skip = false, $before = ”, $after = ”){
    static $debug_whereat_counter; if( !$debug_whereat_counter) $debug_whereat_counter = 0;
    $uid = $debug_whereat_counter++;
    ?>
    <div class=”debug trace”>
    <?php echo $before; ?>
    <table>
    <thead><tr>
    <th id=”th-index-<?=$uid?>”><i>nth</i></th>
    <th id=”th-line-<?=$uid?>”>Line</th>
    <th id=”th-file-<?=$uid?>”>File</th>
    <th id=”th-method-<?=$uid?>”>Method</th>
    </tr></thead>
    <tbody>
    <?php

    $backtrace = debug_backtrace();
    if( $skip ) $backtrace = array_slice($backtrace, $skip);

    foreach($backtrace as $index => $trace){
    //force quit
    if($limit !== false && $index == $limit){
    ?>
    <tr><td colspan=”4″><em>—– FORCE STOP RECURSION —–</em></td></tr>
    <?php
    break;
    }

    ?>
    <tr class=”trace-item”>
    <th headers=”th-index-<?=$uid?>”><?=$index?></th>
    <td headers=”th-line-<?=$uid?>” class=”line”><?=$trace[‘line’]?></td>
    <td headers=”th-file-<?=$uid?>” class=”file”><?=$trace[‘file’]?></td>
    <td headers=”th-method-<?=$uid?>” class=”method”>
    <code><?=$trace[‘function’]?></code>
    <?php
    if(!empty($trace[‘args’])){
    echo ‘<br />’;
    while(!empty($trace[‘args’])){
    ?> {<i><?php print_r(array_shift($trace[‘args’]) ); ?></i>} <?php
    }// while !empty $trace[‘args’]
    }
    ?>
    </td>
    </tr>
    <?php
    }
    ?>
    </tbody></table><?php echo $after; ?></div>
    <?php

    }// function debug_whereat
    [/php]

  • WordPress 3.3 Shortcode Issue

    If you find yourself scratching your head over why your shortcodes have stopped working in WordPress 3.3, we’ve discovered a funny quirk. Granted, this fix may actually be the right way to call all shortcodes, but previously we’ve been able to lazily call it directly from our functions.php file and no one cared. But, now it seems, with the upgrade, that WordPress 3.3 does care. It requires your add_shortcode() function to be called within their init() hook. Calling it directly after your newly declared shortcode function won’t work anymore.

    The lazy method we got away with before:

    [php]
    function abtcore_shortcode_button( $atts, $content = null ) {
    extract( shortcode_atts( array(
    ‘color’ => ‘blue’
    ), $atts ) );
    return ‘<p>’ . $content . ‘</p>’;
    }

    add_shortcode( ‘button’, ‘abtcore_shortcode_button’ );
    [/php]

    The better way that is now required by WordPress 3.3:

    [php highlight=”7″]
    function abtcore_shortcode_button( $atts, $content = null ) {
    extract( shortcode_atts( array(
    ‘color’ => ‘blue’
    ), $atts ) );
    return ‘<p>’ . $content . ‘</p>’;
    }
    add_action(‘init’, ‘abtcore_register_my_shortcodes’, 100);
    function abtcore_register_my_shortcodes() {
    add_shortcode( ‘button’, ‘abtcore_shortcode_button’ );
    }
    [/php]

    Notice the add_action() call on the ‘init’ on line 7. This will properly register your shortcode function when WordPress initiates.

    I hope this helps.

  • Business Intelligence Dashboards: The best thing since sliced bread?

    I hate how complicated my Web Analytics tool seems to be.  Why can’t it be smart and show me what I need to know?

    The speed in which your internet marketer identifies wins and losses is vital to your businesses success.  However, in most cases – businesses fail to realize just how important that human element is when it comes to internet marketing.  Web Analytics is an ever changing box of puzzle pieces that define how and why your online presence benefits your businesses success.  As you put the pieces together to create a clearer picture of how your website is doing and what is driving outcomes rather than failures, you will begin to realize any ā€œwastedā€ time spent on data analysis translates to opportunity cost that could be invested into creating new pieces to yield.  The above situation is a catch-22 though; because on the flipside creating pieces without data analysis leads to overhead when incorrect pieces are made that simply do not fit.

    You better be creating a business intelligence dashboard before the deep-dive.

    Here are my two conclusions in regards to data analysis versus making marketing moves online.

    1. You are damned if you do too much data analysis and you are damned if you don’t do enough data analysis.
    2. Let’s make it easier for the internet marketer to see the relevant data that helps them decide which pieces need to be created.  (Custom dashboards!)

    There is such a thing of digging your own grave when it comes to data analysis.  Focusing on the wrong metrics and the wrong dimensions can lead to this.

    Defining your custom dashboards based off of which business questions and marketing channels you are analyzing will save you lots of time and avoid unnecessary digging.

    Here is a scenario I have encountered myself during my tenure at Atlantic Business Technologies.

    My rules of thumbs when creating business intelligence dashboards in Google Analytics

    Take the time to define which groupings of metrics, segments and dimensions you plan to keep track of a day.  My golden rules for data and dashboards are the following:

    1. If you can’t explain how the data affects the bottom line of your business, don’t include it.
    2. If you can’t drill deeper into the dashboard, it is most likely too specific of a report to be considered a dashboard.
    3. If you don’t have at least one dashboard that focuses on growth opportunities, make one.
    4. Grow a habit of using the dashboards frequently.
    5. Grow the dashboard as needed.  Adapt.

    Some examples of dashboards I’ve created:

    Visitor / Client Retention (Customer Lifetime Value)

    -# of Visits for returning visitors.

    -Bounce Rate

    -Traffic Sources of Returning members

    -Trend data for Facebook / Twitter for Returning visitors

    -Top Content viewed by these individuals

    -Days from last visit

    Market Channel Performance (focused on new visits / conversions and conversion rate)

    -New Visits broken out by marketing channel which includes SEO, PPC, Email, Direct / Branded Searches and Referral traffic

    -Conversion Rate by channel

    -Total conversions by channel

    -Bounce rate by channel

    Non-Branded SEO Channel Performance

    Total # of visits

    -Top 10 visits by state

    -Top 10 goals by state

    -Conversions by sport type

    -Landing pages compared to bounce rate

    -Keywords that did not lead to conversions

    -Keywords that lead to conversions

    Pay Per Click Channel Performance

    Total # of visits

    -Top 10 visits by state

    -Top 10 goals by state

    -Conversions by sport type

    -Landing pages compared to bounce rate

    -Keywords that did not lead to conversions

    -Keywords that lead to conversions

    -Conversions by Campaign

    -Total Cost vs. Total Conversions

    Market Channel Performance (focused on new visits / conversions and conversion rate)

    -New Visits broken out by marketing channel which includes SEO, PPC, Email, Direct / Branded Searches and Referral traffic

    -Conversion Rate by channel

    -Total conversions by channel

    -Bounce rate by channel

    My question to you is this, what dashboards would you create for your business and why?