-
Lacey-Anne Sanderson (both days)
-
Katheryn Buble (both days)
-
Valentin Guignon (both days)
-
Nic Herndon (both days)
-
Emily Grau (both days)
-
Eric Wafula (both days, beginner)
-
Prakash Timilsena (both days, beginner)
-
Meg Staton (meeting only)
-
Abdullah Almsaeed (both days)
-
Ming Chen (both days)
-
Steven Cannon (day 1 and first half of day 2)
-
Eliot Cline (both days)
-
Sudhansu Dash (day 1 and first half of day 2; beginner)
-
Luca Bianco (day 1; beginner)
-
Chris Childers (both days)
-
Ethy Cannon (1 ½ days)
-
Qiaoshan Lin (both days)
-
Sofia Robb (both days)
-
Taein Lee (both days)
-
Victor Unda (both days)
Thursday, January 12
-
Tripal Download API: Implementing common download formats
-
Draft Guidelines for how to make a module “sharable”
-
How to make a Tripal module and make it shareable(for beginners)
-
Having fun with D3JS (developing a module to display Chado phylotree, VG)
-
Adding custom fields to search API indexation (VG)
-
Implementing a cart using Flag module (VG)
-
Uses and setup of Tripal Multi-Chado (VG)
-
Drupal forms, AJAX
-
The Tripal Job Launcher
-
Module Development with sharing in mind
-
Tripal Download API
-
Using D3.js to display Chado Phylotree
Topic #1: How to make a Tripal module and make it shareable
The first time we attempted to break out into groups it became evident everyone wanted an introduction to making Tripal modules with tips on developing with sharing in mind. As such Lacey with help from other developers in the room gave an impromptu talk with examples:
-
Tripal Example Module (distrubuted with Tripal core): https://github.com/tripal/tripal/tree/7.x-2.x/tripal_example
-
This module has examples of many of the Tripal API functions
-
It was discussed that these examples would be more helpful broken into multiple modules similar to the Drupal Example module
-
-
Tripal API: http://api.tripal.info/api/tripal/2.x
-
Devel module: use dpm($var, ‘label’);
-
Follow drupal coding standards: https://www.drupal.org/docs/develop/standards
-
There is module to check coding standards (https://www.drupal.org/project/coder)
-
Another Drupal module will extract your API if function comments are properly coded (https://www.drupal.org/project/api)
-
If your (custom) module is on the Drupal git (even in your sandbox), you can use https://pareview.sh/pareview/ to verify your code against Drupal standards.
-
-
Make a configuration form
-
This way every time you are tempted to hard-code something you have a place to quickly add a form element allowing it to be configured instead :-)
-
Use variable_get() and variable_set() to set configuration values for use elsewhere in your module
-
-
https://github.com/tripal/tripal/blob/7.x-2.x/tripal_example/includes/tripal_example.admin.inc#L50
-
https://github.com/UofS-Pulse-Binfo/nd_genotypes/blob/7.x-2.x/includes/nd_genotypes.admin.inc#L38
-
-
When making a form you tell drupal to use the form api in hook_menu
-
Try to follow file-naming conventions and put code in the “usual” files. Being able to put most code pretty much anywhere can make it challenging to find bits of code.
-
Be careful with naming of Drupal variables to avoid conflicting with variables used by other variables, preferably prefaced with [machine] module name.
-
Likewise, function names should all be prefaced with [machine] module name
-
Choose a short, descriptive, unique machine name for the module. Note that this name is then used to prefix function and Drupal variable names; there is a limit on the length of Drupal variable names.
-
The module should be customizable.
-
Create hooks
-
Tripal 2: override templates - template name is displayed in admin “blue box” if logged in.
-
Tripal 3: don’t override templates (migrating to Twig templates), instead use Drupal Field API. Also enables use of different storage backends.
-
Your own custom hooks: https://www.drupal.org/docs/7/creating-custom-modules/creating-drupal-7-hooks Take care the hooks have unique names.
-
-
Methods for altering a modules weight(d7 and d8)
-
Might want to separate generic and specific code into a core module and a customization of the core module. The core module would then be more shareable.
-
Create default templates inside module; put specific themes in your theme directory.
-
If your module implements hook_init, you need to make sure it will be loaded after Tripal has been initialized. To do so, you need to set the weight of your module to be higher than Tripal’s one. That’s done in your hook_install implementation with a piece of code like this:
// Set loading order for tripal core.
$tripal_weight = 0; // needs to be filled with Tripal core or other Tripal modules weight
$sql_query = "UPDATE {system} SET weight = " . ($tripal_weight + 1) . " WHERE name = 'tripal_mymodule';";
db_query($sql_query); -
Materialized Views can adapt to varying methods of story data in chado.
Topic #2a: Tripal Download API
-
Lead: Lacey Sanderson
-
Participants:
-
Emily Grau
-
Lacey Sanderson
-
Sofia Robb
-
Victor Unda
-
Taein Lee
-
Luca Bianco
-
Abdullah Almsaeed
-
Ethy
-
-
Tripal Download API Code/Documentation: https://github.com/tripal/trpdownload_api
-
Format Implementations developed during hackathon:
-
FASTA
-
Group: Abdullah Almsaeed
-
https://github.com/statonlab/trpdownload_api_feature (example implementation includes FASTA file)
-
Create a fasta file line https://gist.github.com/almasaeed2010/2f7874c15ecc2e5872678ecfa26bf7bb
-
-
Expression data of a feature
-
Group Members: Sofia Robb, Ethy Cannon, Emily Grau
-
-
Organism CSV from the organism view
-
Group Members: Luca Bianco, Victor Unda
-
https://gist.github.com/Viktoru/eb487b6f1c4205ef2a08e51e72f873d2
-
-
-
How to add a link to an existing view (example: Adds “Download: GFF3” link to the current page. Link includes query arguments)
-
Edit the Drupal view
-
Add a “Global: Text Area” under Header
-
Change format to PHP code
-
Add the following code:
<?php
-
-
$query = drupal_get_query_parameters();
?>
Download: <?php print l('GFF3', current_path() . '/gff3', array('target' => '_blank', 'query' => $query)); ?>
-
Save the view
Topic #2b: Having fun with D3JS (developing a module to display Chado phylotree)
-
Lead: Valentin Guignon
-
Participants:
-
Ming Chen
-
Katheryn Buble
-
Nic Herndon
-
Chris Childers
-
Qiaoshan Lin
-
Sudhansu Dash
-
Eric Wafula
-
Prakash Raj
-
Eliot Cline
-
-
UPDATE: the result is available here:
https://github.com/tripal/tripal_dt -
Setup: create a custom module copy of the tripal_example module
cd <drupal_sites_directory>/all/modules/
cp -r tripal/tripal_example tripal_dt
cd tripal_dt
mv tripal_example.info tripal_dt.info
mv tripal_example.install tripal_dt.install
mv tripal_example.module tripal_dt.module
mv theme/css/tripal_example.css theme/css/tripal_dt.css
mv theme/templates/tripal_example_base.tpl.php theme/templates/tripal_dt_tree_page.tpl.php
-
Here is how your tripal_dt.info file should look like:
name = Tripal Demo Tree
description = A tree module for Tripal.
core = 7.x
project = tripal_dt
package = Tripal Extensions
version = 7.x-2.0
dependencies[] = tripal_core
dependencies[] = tripal_views
dependencies[] = tripal_db
dependencies[] = tripal_cv
-
Open your tripal_dt.install file and only keep the function “tripal_example_requirements” and rename it into “tripal_dt_requirements”
-
Open the tripal_dt.module file
keep only the first two require() lines and change names ( the api and theme requirements)
Remove the hook_permissions implementation (we don’t need them in our case).
Keep the hook_menu implementation and rename it:
function tripal_dt_menu() {
$items = array();
$items['tripal_dt'] = array(
'title' => Demo Tree',
'description' => 'A nice D3JS demo tree.',
'page callback' => 'theme',
'page arguments' => array('tripal_dt_tree'),
'access callback' => TRUE,
'type' => MENU_NORMAL_ITEM,
);
return $items;
}
We keep the hook_theme implementation (and rename it):
function tripal_dt_theme($existing, $type, $theme, $path) {
$items = array(
'tripal_dt_tree' => array(
'template' => 'tripal_dt_tree_page',
'variables' => array(),
'path' => "$path/theme/templates",
),
);
return $items;
}
And just remove other functions! :)
-
Now edit themes/tripal_dt.theme.inc and only keep one function:
function tripal_dt_preprocess_tripal_dt_tree(&$variables) {
// Adds the appropriate JS and CSS specific to our page.
// Note: those scripts won't be loaded on other pages!
drupal_add_js(drupal_get_path('module', 'tripal_dt') .'/theme/js/d3.min.js');
drupal_add_js(drupal_get_path('module', 'tripal_dt') .'/theme/js/d3.dndtree.js');
drupal_add_css(drupal_get_path('module', 'tripal_dt') .'/theme/css/tripal_dt.css');
$phylotree_id = 1; // our dataset phylotree_id
// Loads phylonode records from the database.
// Note: this process can be long/heavy so it might be a good idea to use
// Drupal cache features and load the structure from cache if it has already
// been generated once and saved into cache.
$columns = array('phylonode_id', 'parent_phylonode_id', 'label');
$values = array(
'phylotree_id' => $phylotree_id,
);
$options = array(
'order_by' => array(
'phylonode_id' => 'ASC',
),
);
$phylonodes = chado_select_record(
'phylonode',
$columns,
$values,
$options
);
// Raw data table stuff.
$header = array(
t('phylonode_id'),
t('Parent'),
t('Name'),
);
$rows = array();
// JSON data stuff.
$tree_data = array(); // Store D3 tree structure.
$node_lookup = array(); // Associate a Chado ID to a D3 node ID.
$node_index = 1; // Used to generate D3 IDs starting from 1.
// Process each node and fill the data.
foreach ($phylonodes as $phylonode) {
// Fill raw data table.
$rows[] = array(
$phylonode->phylonode_id,
$phylonode->parent_phylonode_id,
$phylonode->label,
);
// Generate the tree structure.
// Get current phylnode Chado ID.
$phylonode_id = $phylonode->phylonode_id;
// Fill lookup table.
$node_lookup[$phylonode_id] = $node_index;
// Store node data.
$tree_data[$node_index] = array(
'id' => $node_index,
'name' => $phylonode->label,
);
// Check if node has a parent and if so, add it to its parent.
if ($parent_id = $phylonode->parent_phylonode_id) {
// Is it the first child?
$parent_node_id = $node_lookup[$parent_id];
if (!array_key_exists('children', $tree_data[$parent_node_id])) {
// Yes, add a new children array to parent.
$tree_data[$parent_node_id]['children'] = array(
&$tree_data[$node_index]
);
}
else {
// No, add child to its siblings.
$tree_data[$parent_node_id]['children'][] =
&$tree_data[$node_index];
}
}
// Next node.
++$node_index;
}
$variables['table'] = array('header' => $header, 'rows' => $rows);
$variables['tree'] = $tree_data[1];
}
-
Edit theme/templates/tripal_dt_tree_page.tpl.php and fill it with:
<h2>Tree raw data</h2>
<?php
echo theme('table', $table);
?>
<br/>
<h2>Tree structure</h2>
<pre>
<?php
echo json_encode(
$tree,
JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES
);
?>
</pre>
<br/>
<h2>Tree</h2>
<div id="tripal_dt-tree">
</div>
<script>
jQuery(function() {
var tree_data = <?php print json_encode($tree); ?>;
Drupal.tripal_dt.renderD3JSTree(tree_data);
});
</script>
Now we need some data to work on, into chado. Here is an example dataset:
INSERT INTO phylotree VALUES (1, 1, 'Testing tree', 1, NULL, 'A tree for testing');
INSERT INTO phylonode VALUES
(1, 1, NULL, 1, 14, 1, NULL, 'Musaceae', NULL),
(2, 1, 1, 2, 9, 1, NULL, 'Musa', NULL),
(3, 1, 1, 10, 13, 1, NULL, 'Ensete', NULL),
(4, 1, 2, 3, 8, 1, NULL, 'Eumusa', NULL),
(5, 1, 4, 4, 5, 1, NULL, 'acuminata', NULL),
(6, 1, 4, 6, 7, 1, NULL, 'balbisiana', NULL),
(7, 1, 3, 11, 12, 1, NULL, 'lasiocarpa', NULL)
;
This dataset represents a subpart of the banana species taxonomy:
1#Musaceae#14
/ °°°°°°°°°°\
2#Musa#9 10#Ensete#13
| |
3#Eumusa#8 11#lasiocarpa#12
| °°°°°°°°°°\
4#acuminata#5 6#balbisiana#7
You need to add the 2 following JS files into tripal_dt/theme/js/:
-
Modified d3.dndtree for Tripal hackathon @ PAG 2017
-
D3 Min JS for Tripal hackathon @PAG2017
-
Associated CSS file tripal_dt.css:
All thoses files are available there: https://github.com/tripal/tripal_dt