How to add html to the "My user points" page (user points module) I am building a Drupal 7 site using the User Points module.

I have some issues that I am not able to solve, you can see the issue here.
I can go around these issues if I will be able to edit the HTML of the "my user points" page (the page that every user can see the points he got and the reason he got them).


Mainly, I want to add a link in this page, that will link to another page on my site.
In addition, I want to add some text beneath the title of the page (original title).
Third thing I want to do is make sure the output on the "Reason column" will be longer, and won't cut off and be too short with "..." in the end.



How can I achieve that?

Where and how I can find the HTML of this page, and edit &amp; add some HTML code?
You can find the menu path defined for " My User Points " page in userpoints.module file in hook_menu implementation..

  $items['myuserpoints'] = array(
    'title' =&gt; 'My !points',
    'title arguments' =&gt; userpoints_translation(),
    'page callback' =&gt; 'drupal_get_form',
    'page arguments' =&gt; array('userpoints_list_transactions'),
    'access callback' =&gt; 'userpoints_access_my_points',
    'file' =&gt; 'userpoints.pages.inc',
    'type' =&gt; MENU_NORMAL_ITEM,
    'menu_name' =&gt; 'user-menu',
  );


As you see above..

Page callback drupal_get_from with arguments "userpoints_list_transactions" is defined in "userpoints.pages.inc" file...

/**
 * Displays a detailed transaction report for an individual user.
 *
 * @param $account
 *   For which account to display. Defaults to the current user.
 */
function userpoints_list_transactions($form, &amp;$form_state, $account = NULL, $tid = NULL) {

  // If this is an AJAX request, update $_GET['q'] so that table sorting and
  // similar links are using the correct base path.
  if ($_GET['q'] == 'system/ajax') {
    $q = 'myuserpoints';
    if (!empty($account)) {
      $q = 'user/' . $account-&gt;uid . '/points';
    }
    $_GET['q'] = $q;
  }

  if (empty($account)) {
    global $user;
    $account = $user;
  }

  $settings = array(
    'show_user' =&gt; FALSE,
  );
  $header = userpoints_get_transaction_header($settings);

  $query = db_select('userpoints_txn', 'p')-&gt;extend('PagerDefault')-&gt;extend('TableSort')
    -&gt;fields('p')
    -&gt;condition('p.uid', $account-&gt;uid)
    -&gt;orderByHeader($header)
    // Enforce consistent sort order.
    -&gt;orderBy('p.txn_id', 'DESC')
    -&gt;limit(variable_get(USERPOINTS_REPORT_LIMIT, 10));

  if (module_exists('taxonomy')) {
    $query-&gt;leftJoin('taxonomy_term_data', 't', 'p.tid = t.tid');
  }

  $unapproved_query = db_select('userpoints_txn', 'p')
    -&gt;condition('uid', $account-&gt;uid)
    -&gt;condition('status', USERPOINTS_TXN_STATUS_PENDING);
  $unapproved_query-&gt;addExpression('SUM(points)');

  $values = userpoints_filter_parse_input($form_state, $tid);
  $active_category = userpoints_filter_query($query, $values);
  userpoints_filter_query($unapproved_query, $values);

  if (isset($active_category)) {
    drupal_set_title(t('!Points for @username (%category category)', userpoints_translation() + array('%category' =&gt; $active_category, '@username' =&gt; format_username($account))), PASS_THROUGH);
    $total_title = t('Total !points (%category category)', userpoints_translation() + array('%category' =&gt; $active_category));
  }
  else {
    drupal_set_title(t('!Points for @username', userpoints_translation() + array('@username' =&gt; format_username($account))));
    $total_title = t('Total !points', userpoints_translation());
  }

  $rows = array();
  foreach ($query-&gt;execute() as $transaction) {
    $rows[] = userpoints_get_transaction_row($transaction, $settings);
  }

  // Store context in the output array so that modules have access to it.
  $output = array(
    '#account' =&gt; $account,
    '#attached' =&gt; array(
      'css' =&gt; array(
        drupal_get_path('module', 'userpoints') . '/userpoints.css',
      ),
    ),
  );

  $output['form'] = userpoints_filter_form($account, $values);

  $output['list'] = array(
    '#type' =&gt; 'container',
    '#id' =&gt; 'userpoints_list_wrapper',
  );
  $output['list']['table'] = array(
    '#theme' =&gt; 'table',
    '#header' =&gt; $header,
    '#rows' =&gt; $rows,
    '#empty' =&gt; t('No !Points earned', userpoints_translation()),
    '#weight' =&gt; -5,
    '#attributes' =&gt; array('class' =&gt; array('userpoints-myuserpoints-list')),
  );
  $output['list']['pager'] = array(
    '#markup' =&gt; theme('pager'),
    '#weight' =&gt; 0,
  );

  // Fetch pending (not yet approved) points according to the category filter.
  $pending = (int)$unapproved_query
    -&gt;execute()
    -&gt;fetchField();

  // Display both pending and approved points in a simple table.
  $output['list']['summary_table'] = array(
    '#theme' =&gt; 'table',
    '#header' =&gt; array(
      array(
        'data' =&gt; $total_title,
        'colspan' =&gt; 2,
      ),
    ),
    '#rows' =&gt; array(
      array(
        'data' =&gt; array(t('Approved !points', userpoints_translation()), userpoints_get_current_points($account-&gt;uid, isset($values['tid']) ? $values['tid'] : 'all')),
        'class' =&gt; array('userpoints-myuserpoints-total-approved'),
      ),
      array(
        'data' =&gt; array(t('Pending !points', userpoints_translation()), $pending),
        'class' =&gt; array('userpoints-myuserpoints-total-pending'),
      ),
    ),
    '#weight' =&gt; 10,
    '#attributes' =&gt; array('class' =&gt; array('userpoints-myuserpoints-total')),
  );

  // For simplicity, the generated output is passed to a custom alter function.
  // This would also be possible through hook_page_alter(), but that hook is
  // hard to use.
  drupal_alter('userpoints_list_transactions', $output);

  return $output;
}


In the end you can see generated output is passed to a custom alter function

  drupal_alter('userpoints_list_transactions', $output);


By implementing hook_TYPE_alter()  in your custom module you can able to change the output..
i.e YOURMODULENAME_userpoints_list_transactions_alter function you need to implement..

/**
 * Implements hook_userpoints_list_transactions().
 */
function MODULENAME_userpoints_list_transactions_alter(&amp;$output) {
  // you can now change $output directly here
}


$output is a form variable.. You can add a new element to $output ..

/**
 * Implements hook_userpoints_list_transactions().
 */
function MODULENAME_userpoints_list_transactions_alter(&amp;$output) {
  // you can now change $output directly here
  $output['custom_text']['my_link'] = array(
    '#markup' =&gt; l("LINK", "Your Link"),
  );
  $output['custom_text']['my_text'] = array(
    '#markup' =&gt; 'Blah Blah',
  );
}