Skip to content

Commit

Permalink
Merge pull request #1169 from tripal/100-tv3-gene_pages
Browse files Browse the repository at this point in the history
Customizable Transcripts on Gene Pages
  • Loading branch information
spficklin committed Mar 2, 2021
2 parents 27066e8 + bd64367 commit c3b2392
Show file tree
Hide file tree
Showing 15 changed files with 609 additions and 30 deletions.
Binary file modified docs/user_guide/example_genomics/genomes_genes.5.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
28 changes: 27 additions & 1 deletion docs/user_guide/example_genomics/genomes_genes.rst
Original file line number Diff line number Diff line change
Expand Up @@ -191,7 +191,7 @@ Now the scaffold sequence and mRNA sequences are loaded!
It is not required to load the mRNA sequences as those can be derived from their alignments with the scaffold sequence. However, in Chado the **feature** table has a **residues** column. Therefore, it is best practice to load the sequence when possible.

Creating Gene Pages
----------------------
-------------------
Now that we've loaded our feature data, we must publish them. This is different than when we manually created our Organism and Analysis pages. Using the GFF and FASTA loaders we imported our data into Chado, but currently there are no published pages for this data that we loaded. To publish these genomic features, navigating to Structure → Tripal Content Types and click the link titled Publish Chado Content. The following page appears:

.. image:: genomes_genes.3.png
Expand Down Expand Up @@ -252,3 +252,29 @@ Next find an mRNA page to view. Remember when we loaded our FASTA file for mRNA
- We associated the Phytozome accession with the features using a regular expression when importing the FASTA file.

All data that appears on the page is derived from the GFF file and the FASTA files we loaded.


Customizing Transcripts on Gene Pages
-------------------------------------
By default the gene pages provided by Tripal will have a link in the sidebar table of contents named **Transcripts** and when clicked a table appears that lists all of the transcripts (or mRNA) that belong to the gene. The user can click to view more information about each published transcript.

.. image:: genomes_genes.6.png

Sometimes however, more than just a listing of transcripts is desired on a gene page. You can customize the information that is presented about each transcript by navigating to the gene content type at **Structure → Tripal Content Types** and clicking **mange fields** in the **Gene** row. This page allows you to customize the way fields are displayed on the gene page. Scroll down the page to the **Transcript** row and click the **edit** button. The following page should appear.

.. image:: genomes_genes.7.png

Open the field set titled **Transcript (mRNA) Field Selection** to view a table that lists all of the available fields for a transcript.

.. image:: genomes_genes.8.png

On this page you can check the boxes next to the field that you want to show for a transcript on the gene page. For this example, we will select the fields **Name**, **Identifier**, **Resource Type**, **Anotations**, and **Sequences** (they may not be in this order on your own site). You can control the order in which fields will be shown by dragging them using the crosshairs icon next to each one. Scroll to the bottom of the page and click the **Save Settings** button.

Next return to the gene page, reload it, and click on the **Transcripts** link. Now you are provided a select box with the transcript names. When a transcript is selected, the pane below will populate with the fields that you selected when editing in the Transcript field.

.. image:: genomes_genes.9.png

You can return to the Transcript field edit page under the Gene content type at any time to add, remove or change the order of fields that appear for the transcript.

.. note::
Transcripts on a gene page can only be customized if all of them are published. If not, the default table listing is shown.
55 changes: 55 additions & 0 deletions tripal/includes/TripalFields/TripalField.inc
Original file line number Diff line number Diff line change
Expand Up @@ -633,9 +633,16 @@ class TripalField {
}

/**
* Validates the instance settings form.
*
* Remember if you used the 'themeable' option for form elements you
* must copy the values correctly. See the description in hte
* `instanceSettingsForm()` function for details.
*
* @param $form
* The form object.
* @param $form_state
* The form_state object.
*/
public function settingsFormValidate($form, &$form_state) {

Expand All @@ -656,6 +663,17 @@ class TripalField {
* $element = parent::instanceSettingsForm();
* @endcode
*
* Additinally, theming of the instance setting form is not supported by
* Drupal, but Tripal will allow you to theme form elements if you
* place them in the $element['themeable'] variable. However, if you place
* form elements there you must set corresponding form elements of type
* 'value' at the base level of the element array and copy appropriate
* settings values from the
* $form_state['values']['instance']['settings']['themeable'] variable into
* the
* $form_state['values']['instance']['settings'] variable. Do this in the
* `instanceSettingsFormValidate()` function.
*
* Please note, the form generated with this function does not easily
* support AJAX calls in the same way that other Drupal forms do. If you
* need to use AJAX you must manually alter the $form in your ajax call.
Expand All @@ -668,10 +686,47 @@ class TripalField {

$element['#field'] = $this->field;
$element['#instance'] = $this->instance;
$element['themeable'] = [];
$element['themeable']['#field'] = $this->field;
$element['themeable']['#instance'] = $this->instance;
$element['themeable']['#theme'] = 'tripal_field_settings_default';
$element['#element_validate'][] = 'tripal_field_instance_settings_form_validate';
return $element;
}

/**
* The theme function for the instance settings form.
*
* @param $element
* A form element array containing basic properties for the widget:
* - #entity_type: The name of the entity the field is attached to.
* - #bundle: The name of the field bundle the field is contained in.
* - #field_name: The name of the field.
* - #language: The language the field is being edited in.
* - #field_parents: The 'parents' space for the field in the form. Most
* widgets can simply overlook this property. This identifies the location
* where the field values are placed within $form_state['values'], and is
* used to access processing information for the field through the
* field_form_get_state() and field_form_set_state() functions.
* - #columns: A list of field storage columns of the field.
* - #title: The sanitized element label for the field instance, ready for
* output.
* - #description: The sanitized element description for the field instance,
* ready for output.
* - #required: A Boolean indicating whether the element value is required;
* for required multiple value fields, only the first widget's values are
* required.
* - #delta: The order of this item in the array of subelements; see
* $delta above
*
* @return
* A drupal renderable array or HTML or an empty string if no
* theming is to be applied.
*/
public function settingsTheme($element) {

}

/**
* Provides validation of the instance settings form.
*
Expand Down
23 changes: 21 additions & 2 deletions tripal/includes/tripal.fields.inc
Original file line number Diff line number Diff line change
Expand Up @@ -445,7 +445,8 @@ function tripal_field_instance_settings_form($field, $instance) {
$field_class = $field['type'];
if (tripal_load_include_field_class($field_class)) {
$field = new $field_class($field, $instance);
return $field->instanceSettingsForm();
$form = $field->instanceSettingsForm();
return $form;
}
}

Expand Down Expand Up @@ -827,7 +828,6 @@ function tripal_field_formatter_settings_form($field, $instance,
$formatter = new $formatter_class($field, $instance);
$elements = $formatter->settingsForm($view_mode, $form, $form_state);
}

return $elements;
}

Expand Down Expand Up @@ -928,6 +928,7 @@ function tripal_form_field_ui_display_overview_form_alter(&$form, &$form_state,
* @param $variables
*/
function theme_tripal_field_default($variables) {

$element = $variables['element'];
$field = $element['#field'];
$instance = $element['#instance'];
Expand All @@ -940,3 +941,21 @@ function theme_tripal_field_default($variables) {
return $widget->theme($element);
}
}

/**
* Theme function for all TripalFieldWidget objects.
*
* @param $variables
*/
function theme_tripal_field_settings_default($variables) {

$element = $variables['element'];
$field = $element['#field'];
$instance = $element['#instance'];
$field_class = $element['#field']['field_name'];
tripal_load_include_field_class($field_class);
if (class_exists($field_class)) {
$field = new $field_class($field, $instance);
return $field->settingsTheme($element);
}
}
7 changes: 6 additions & 1 deletion tripal/tripal.module
Original file line number Diff line number Diff line change
Expand Up @@ -817,6 +817,11 @@ function tripal_theme($existing, $type, $theme, $path) {
'render element' => 'element',
'file' => 'includes/tripal.fields.inc',
),
// Theming for all field settings forms.
'tripal_field_settings_default' => array(
'render element' => 'element',
'file' => 'includes/tripal.fields.inc',
),
// Themed forms
'tripal_views_handler_area_collections_fields_fset' => array(
'render element' => 'form',
Expand Down Expand Up @@ -1657,7 +1662,7 @@ function tripal_job_describe_args($callback, $args) {

/**
* Returns the current version of Tripal, according to the tripal.info file
*
*
* @return string
* The version string of Tripal. Ex. 7.x-3.1
*/
Expand Down
2 changes: 2 additions & 0 deletions tripal_chado/includes/TripalFields/ChadoField.inc
Original file line number Diff line number Diff line change
Expand Up @@ -323,6 +323,8 @@ class ChadoField extends TripalField {
* @see TripalField::instanceSettingsForm()
*/
public function instanceSettingsForm() {
$element = parent::instanceSettingsForm();

// Make sure we don't lose our Chado table mappings when the settings
// are updated. Setting them as values in the form ensures they don't
// get accidentally overwritten.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -178,7 +178,7 @@ class data__accession_widget extends ChadoFieldWidget {
$fieldset = [
'#title' => $element['#title'],
'#value' => '',
'#description' => $element['#description'],
'#description' => $element['#description'],
'#children' => $layout,
];

Expand Down
171 changes: 170 additions & 1 deletion tripal_chado/includes/TripalFields/so__transcript/so__transcript.inc
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,10 @@ class so__transcript extends ChadoField {
// type. This will create form elements when editing the field instance
// to allow the site admin to change the term settings above.
'term_fixed' => FALSE,
// Contains the list of fields on the transcript child that the
// user wants to have displayed for the transcript. The
// `so__transcript_expanded_formatter will display these.
'transcript_fields' => []
];

// The default widget for this field.
Expand Down Expand Up @@ -183,4 +187,169 @@ class so__transcript extends ChadoField {
}
}

}
/**
* @see TripalField::globalSettingsForm()
*/
public function instanceSettingsForm() {
$element = parent::instanceSettingsForm();

$settings = $this->instance['settings'];


$element['transcript_fields'] = [
'#type' => 'value',
'#default_value' => $settings['transcript_fields'],
];

// Get the content type for the mRNA term (SO:0000234) and it's feilds.
// If it isn't published then don't show the form below.
$bundle = tripal_load_bundle_entity(['accession' => 'SO:0000234']);
if (!$bundle) {
return $element;
}

$fields = field_info_instances('TripalEntity', $bundle->name);

foreach ($fields as $field_name => $details) {

$defaults = [];
if (array_key_exists($field_name, $settings['transcript_fields'])) {
$defaults = $settings['transcript_fields'][$field_name];
}

$weight = array_key_exists('weight', $defaults) ? $defaults['weight'] : $details['display']['default']['weight'];
$checked = array_key_exists('show', $defaults) ? $defaults['show'] : 0;
$element['themeable']['field-'. $weight] = [
'#type' => 'value',
'#value' => $field_name,
'#weight' => $weight,
];
$element['themeable']['field-'. $weight . '-check'] = [
'#type' => 'checkbox',
'#weight' => $weight,
'#default_value' => $checked,
];
$element['themeable']['field-'. $weight . '-label'] = [
'#type' => 'markup',
'#markup' => t($details['label']),
'#weight' => $weight,
];
$element['themeable']['field-'. $weight . '-description'] = [
'#type' => 'markup',
'#markup' => t($details['description']),
'#weight' => $weight,
];
$element['themeable']['field-'. $weight . '-weight'] = [
'#type' => 'textfield',
'#default_value' => $weight,
'#weight' => $weight,
'#size' => 3,
'#attributes' => [
'class' => ['tripal-field-settings-table-weights'],
],
];
}
return $element;
}

/**
* @see TripalField::instanceSettingsFormValidate()
*/
public function instanceSettingsFormValidate($form, &$form_state) {
$settings = $form_state['values']['instance']['settings']['themeable'];

// Iterate through the themable elements to get the weights and
// checks for each field. Store that info in a temp array.
$temp = [];
foreach ($settings as $element => $value) {
$matches = [];
if (preg_match('/^field-(\d+)-check$/', $element, $matches)) {
$orig_weight = $matches[1];
$new_weight = $settings['field-' . $orig_weight . '-weight'];
$field_name = $settings['field-' . $orig_weight];
$temp[$new_weight]['name'] = $field_name;
$temp[$new_weight]['show'] = $value;
}
}

// Sort and resstart the weights from zero.
ksort($temp);
$temp = array_values($temp);

// Now build the transcirpt_fields setting value.
$transcript_fields = [];
foreach ($temp as $weight => $field) {
$field_name = $field['name'];
$transcript_fields[$field_name] = [
'weight' => $weight,
'show' => $field['show'],
];
}

// Now store the values for the setting properly and remove the unwanted.
$form_state['values']['instance']['settings']['transcript_fields'] = $transcript_fields;
unset($form_state['values']['instance']['settings']['themeable']);
}

/**
* @see TripalField::settingsTheme()
*/
public function settingsTheme($element) {

$headers = ['', 'Field', 'Description', ''];
$rows = [];
foreach (element_children($element) as $child) {
$matches = [];
if (preg_match('/^field-(\d+)-(.+)$/', $child, $matches)) {
$weight = $matches[1];
switch ($matches[2]) {
case 'check':
$rows[$weight]['data'][0] = drupal_render($element[$child]);
break;
case 'label':
$rows[$weight]['data'][1] = drupal_render($element[$child]);
break;
case 'description':
$rows[$weight]['data'][2] = drupal_render($element[$child]);
break;
case 'weight':
$rows[$weight]['data'][3] = drupal_render($element[$child]);
break;
}
ksort($rows[$weight]['data']);
$rows[$weight]['class'] = ['draggable'];
}
}
ksort($rows);

$table = [
'header' => $headers,
'rows' => $rows,
'attributes' => ["id" => 'tripal-field-settings-table'],
'sticky' => TRUE,
'caption' => t('Content Panes Available in the TOC'),
'colgroups' => [],
'empty' => t('There are no content panes for this page. The mRNA content type must exist to customize.'),
];
drupal_add_tabledrag('tripal-field-settings-table', 'order', 'sibling', 'tripal-field-settings-table-weights');

$fset = [];
$fset['fields'] = [
'#type' => 'fieldset',
'#title' => 'Transcript (mRNA) Field Selection',
'#description' => t('Here, you can customize what information is provided to the end-user about transcripts. Select the fields that you want displayed on the page. If no fields are selected then a default display is provided. All mRNA for a gene must be published or the default display will be provided.'),
'#collapsible' => TRUE,
'#collapsed' => TRUE,
'#attributes' => ['class' => ['collapsible', 'collapsed']],
];
drupal_add_library('system', 'drupal.collapse');

$fset['fields']['table'] = [
'#type' => 'markup',
'#markup' => theme_table($table),
];

return drupal_render($fset['fields']);
}

}

0 comments on commit c3b2392

Please sign in to comment.