The way I do this is as follows...
function MYMODULE_block_info() {
$blocks = [];
$blocks['my_block_machine_name'] = [
'info' => t('My Block Title'),
// @see https://api.drupal.org/api/drupal/includes!common.inc/group/block_caching/7.x
// You can use different caching options.
'cache' => DRUPAL_NO_CACHE,
];
return $blocks;
}
function MYMODULE_block_view($delta = '') {
$block = [];
switch ($delta) {
case 'my_block_machine_name':
// Good idea to check user permissions here.
if (user_access('access content')) {
$block['subject'] = t('My Block Title');
$block['content'] = MY_BLOCK_CONTENT_CALLBACK();
}
break;
}
return $block;
}
function MY_BLOCK_CONTENT_CALLBACK()() {
$items = [];
// This is the simplest kind of renderable array.
$items['VAR_ONE'] = ['#markup' => 'VAR_ONE_OUTPUT'];
// Here I added a prefix and a suffix.
$items['VAR_TWO'] = [
'#prefix' => '<div class="foo-bar">',
'#markup' => 'VAR_TWO_OUTPUT',
'#suffix' => '</div>',
];
// This is where the $items get sent to your my-template.tpl.php template
// that got registered below.
return theme('my_cool_block', ['items' => $items]);
}
function MYMODULE_theme() {
// Here you are registering your template for the block output above.
$module_path = drupal_get_path('module', 'MYMODULE');
// Drupal will now look up your modules /theme folder first to grab the
// template.
$base = [
'path' => "$module_path/theme",
];
return [
'my_cool_block' => $base + [
// Leave off .tpl.php.
'template' => 'my-template',
// Define variables you want to pass to the template.
// Here I just pass items, but you can pass any other data as well.
'variables' => [
'items' => NULL,
],
],
];
}
And then in a subfolder in your module called theme
there should be a file called my-template.tpl.php
which could have this in it:
<?php
$items = $variables['items'];
print render($items['VAR_ONE']);
print render($items['VAR_TWO']);
And if you wanted to, you could actually overwrite the "default" module implementation you just made for my-module.tpl.php
in your theme as you wish in block--MYMODULE--DELTA.tpl.php
.