gracefully handle lack of morphological info / capability in rel mapper
Tara L Andrews [Wed, 19 Sep 2012 14:54:34 +0000 (16:54 +0200)]
lib/stemmaweb/Controller/Relation.pm
root/js/relationship-full.js
root/js/relationship-readonly.js
root/src/relate.tt

index 89a7d23..cd0b957 100644 (file)
@@ -127,7 +127,12 @@ sub main :Chained('text') :PathPart('') :Args(0) {
        $c->stash->{'startseg'} = $startseg if defined $startseg;
        $c->stash->{'svg_string'} = $svg_str;
        $c->stash->{'text_title'} = $tradition->name;
-       $c->stash->{'text_lang'} = $tradition->language;
+       if( $tradition->can('language') ) {
+               $c->stash->{'text_lang'} = $tradition->language;
+               $c->stash->{'can_morphologize'} = 1;
+       } else {
+               $c->stash->{'text_lang'} = 'Default';
+       }
        $c->stash->{'template'} = 'relate.tt';
 }
 
@@ -325,49 +330,54 @@ sub reading :Chained('text') :PathPart :Args(1) {
                        $c->stash->{'result'} = { 
                                'error' => 'You do not have permission to view this tradition.' };
                        $c->detach('View::JSON');
+                       return;
                }
                my $errmsg;
-               # Are we re-lemmatizing?
-               if( $c->request->param('relemmatize') ) {
-                       my $nf = $c->request->param('normal_form');
-                       # TODO throw error unless $nf
-                       $rdg->normal_form( $nf );
-                       # TODO throw error if lemmatization fails
-                       # TODO skip this if normal form hasn't changed
-                       $rdg->lemmatize();
-               } else {
-                       # Set all the values that we have for the reading.
-                       # TODO error handling
-                       foreach my $p ( keys %{$c->request->params} ) {
-                               if( $p =~ /^morphology_(\d+)$/ ) {
-                                       # Set the form on the correct lexeme
-                                       my $morphval = $c->request->param( $p );
-                                       next unless $morphval;
-                                       my $midx = $1;
-                                       my $lx = $rdg->lexeme( $midx );
-                                       my $strrep = $rdg->language . ' // ' . $morphval;
-                                       my $idx = $lx->has_form( $strrep );
-                                       unless( defined $idx ) {
-                                               # Make the word form and add it to the lexeme.
-                                               try {
-                                                       $idx = $lx->add_matching_form( $strrep ) - 1;
-                                               } catch( Text::Tradition::Error $e ) {
-                                                       $c->response->status( '403' );
-                                                       $errmsg = $e->message;
-                                               } catch {
-                                                       # Something else went wrong, probably a Moose error
-                                                       $c->response->status( '403' );
-                                                       $errmsg = 'Something went wrong with the request';      
+               if( $rdg && $rdg->does('Text::Tradition::Morphology') ) {
+                       # Are we re-lemmatizing?
+                       if( $c->request->param('relemmatize') ) {
+                               my $nf = $c->request->param('normal_form');
+                               # TODO throw error unless $nf
+                               $rdg->normal_form( $nf );
+                               # TODO throw error if lemmatization fails
+                               # TODO skip this if normal form hasn't changed
+                               $rdg->lemmatize();
+                       } else {
+                               # Set all the values that we have for the reading.
+                               # TODO error handling
+                               foreach my $p ( keys %{$c->request->params} ) {
+                                       if( $p =~ /^morphology_(\d+)$/ ) {
+                                               # Set the form on the correct lexeme
+                                               my $morphval = $c->request->param( $p );
+                                               next unless $morphval;
+                                               my $midx = $1;
+                                               my $lx = $rdg->lexeme( $midx );
+                                               my $strrep = $rdg->language . ' // ' . $morphval;
+                                               my $idx = $lx->has_form( $strrep );
+                                               unless( defined $idx ) {
+                                                       # Make the word form and add it to the lexeme.
+                                                       try {
+                                                               $idx = $lx->add_matching_form( $strrep ) - 1;
+                                                       } catch( Text::Tradition::Error $e ) {
+                                                               $c->response->status( '403' );
+                                                               $errmsg = $e->message;
+                                                       } catch {
+                                                               # Something else went wrong, probably a Moose error
+                                                               $c->response->status( '403' );
+                                                               $errmsg = 'Something went wrong with the request';      
+                                                       }
                                                }
+                                               $lx->disambiguate( $idx ) if defined $idx;
+                                       } elsif( $read_write_keys{$p} ) {
+                                               my $val = _clean_booleans( $rdg, $p, $c->request->param( $p ) );
+                                               $rdg->$p( $val );
                                        }
-                                       $lx->disambiguate( $idx ) if defined $idx;
-                               } elsif( $read_write_keys{$p} ) {
-                                       my $val = _clean_booleans( $rdg, $p, $c->request->param( $p ) );
-                                       $rdg->$p( $val );
-                               }
-                       }               
+                               }               
+                       }
+                       $m->save( $rdg );
+               } else {
+                       $errmsg = "Reading does not exist or cannot be morphologized";
                }
-               $m->save( $rdg );
                $c->stash->{'result'} = $errmsg ? { 'error' => $errmsg }
                        : _reading_struct( $rdg );
 
index b5a9f14..7847571 100644 (file)
@@ -55,26 +55,31 @@ function toggle_checkbox( box, value ) {
 }
 
 function morphology_form ( lexlist ) {
-       $('#morphology').empty();
-       $.each( lexlist, function( idx, lex ) {
-               var morphoptions = [];
-               if( 'wordform_matchlist' in lex ) {
-                       $.each( lex['wordform_matchlist'], function( tdx, tag ) {
-                               var tagstr = stringify_wordform( tag );
-                               morphoptions.push( tagstr );
+       if( lexlist.length ) {
+               $('#morph_outer').show();
+               $('#morphology').empty();
+               $.each( lexlist, function( idx, lex ) {
+                       var morphoptions = [];
+                       if( 'wordform_matchlist' in lex ) {
+                               $.each( lex['wordform_matchlist'], function( tdx, tag ) {
+                                       var tagstr = stringify_wordform( tag );
+                                       morphoptions.push( tagstr );
+                               });
+                       }
+                       var formtag = 'morphology_' + idx;
+                       var formstr = '';
+                       if( 'form' in lex ) {
+                               formstr = stringify_wordform( lex['form'] );
+                       } 
+                       var form_morph_elements = morph_elements( 
+                               formtag, lex['string'], formstr, morphoptions );
+                       $.each( form_morph_elements, function( idx, el ) {
+                               $('#morphology').append( el );
                        });
-               }
-               var formtag = 'morphology_' + idx;
-               var formstr = '';
-               if( 'form' in lex ) {
-                       formstr = stringify_wordform( lex['form'] );
-               } 
-               var form_morph_elements = morph_elements( 
-                       formtag, lex['string'], formstr, morphoptions );
-               $.each( form_morph_elements, function( idx, el ) {
-                       $('#morphology').append( el );
                });
-       });
+       } else {
+               $('#morph_outer').hide();
+       }
 }
 
 function stringify_wordform ( tag ) {
@@ -724,74 +729,79 @@ $(document).ready(function () {
     }
   });
 
-  // function for reading form dialog should go here; for now hide the element
-  $('#reading-form').dialog({
-       autoOpen: false,
-       height: 400,
-       width: 600,
-       modal: true,
-       buttons: {
-               Cancel: function() {
-                       $( this ).dialog( "close" );
-               },
-               Update: function( evt ) {
-                       // Disable the button
-                       $(evt.target).button("disable");
-                       $('#reading_status').empty();
-                       var reading_id = $('#reading_id').val()
-                       form_values = {
-                               'id' : reading_id,
-                               'is_nonsense': $('#reading_is_nonsense').is(':checked'),
-                               'grammar_invalid': $('#reading_grammar_invalid').is(':checked'),
-                               'normal_form': $('#reading_normal_form').val() };
-                       // Add the morphology values
-                       $('.reading_morphology').each( function() {
-                               if( $(this).val() != '(Click to select)' ) {
-                                       var rmid = $(this).attr('id');
-                                       rmid = rmid.substring(8);
-                                       form_values[rmid] = $(this).val();
-                               }
-                       });
-                       // Make the JSON call
-                       ncpath = getReadingURL( reading_id );
-                       var reading_element = readingdata[reading_id];
-                       // $(':button :contains("Update")').attr("disabled", true);
-                       var jqjson = $.post( ncpath, form_values, function(data) {
-                               $.each( data, function(key, value) { 
-                                       reading_element[key] = value;
+  // function for reading form dialog should go here; 
+  // just hide the element for now if we don't have morphology
+  if( can_morphologize ) {
+         $('#reading-form').dialog({
+               autoOpen: false,
+               // height: 400,
+               width: 450,
+               modal: true,
+               buttons: {
+                       Cancel: function() {
+                               $( this ).dialog( "close" );
+                       },
+                       Update: function( evt ) {
+                               // Disable the button
+                               $(evt.target).button("disable");
+                               $('#reading_status').empty();
+                               var reading_id = $('#reading_id').val()
+                               form_values = {
+                                       'id' : reading_id,
+                                       'is_nonsense': $('#reading_is_nonsense').is(':checked'),
+                                       'grammar_invalid': $('#reading_grammar_invalid').is(':checked'),
+                                       'normal_form': $('#reading_normal_form').val() };
+                               // Add the morphology values
+                               $('.reading_morphology').each( function() {
+                                       if( $(this).val() != '(Click to select)' ) {
+                                               var rmid = $(this).attr('id');
+                                               rmid = rmid.substring(8);
+                                               form_values[rmid] = $(this).val();
+                                       }
                                });
-                               if( $('#update_workspace_button').data('locked') == false ) {
-                                       color_inactive( get_ellipse( reading_id ) );
-                               }
-                               $(evt.target).button("enable");
-                               $( "#reading-form" ).dialog( "close" );
-                       });
-                       // Re-color the node if necessary
-                       return false;
-               }
-       },
-       create: function() {
-       },
-       open: function() {
-        $(".ui-widget-overlay").css("background", "none");
-        $("#dialog_overlay").show();
-        $('#reading_status').empty();
-        $("#dialog_overlay").height( $("#enlargement_container").height() );
-        $("#dialog_overlay").width( $("#enlargement_container").innerWidth() );
-        $("#dialog_overlay").offset( $("#enlargement_container").offset() );
-        $("#reading-form").parent().find('.ui-button').button("enable");
-       },
-       close: function() {
-               $("#dialog_overlay").hide();
+                               // Make the JSON call
+                               ncpath = getReadingURL( reading_id );
+                               var reading_element = readingdata[reading_id];
+                               // $(':button :contains("Update")').attr("disabled", true);
+                               var jqjson = $.post( ncpath, form_values, function(data) {
+                                       $.each( data, function(key, value) { 
+                                               reading_element[key] = value;
+                                       });
+                                       if( $('#update_workspace_button').data('locked') == false ) {
+                                               color_inactive( get_ellipse( reading_id ) );
+                                       }
+                                       $(evt.target).button("enable");
+                                       $( "#reading-form" ).dialog( "close" );
+                               });
+                               // Re-color the node if necessary
+                               return false;
+                       }
+               },
+               create: function() {
+               },
+               open: function() {
+                       $(".ui-widget-overlay").css("background", "none");
+                       $("#dialog_overlay").show();
+                       $('#reading_status').empty();
+                       $("#dialog_overlay").height( $("#enlargement_container").height() );
+                       $("#dialog_overlay").width( $("#enlargement_container").innerWidth() );
+                       $("#dialog_overlay").offset( $("#enlargement_container").offset() );
+                       $("#reading-form").parent().find('.ui-button').button("enable");
+               },
+               close: function() {
+                       $("#dialog_overlay").hide();
+               }
+         }).ajaxError( function(event, jqXHR, ajaxSettings, thrownError) {
+                 if( ajaxSettings.url.lastIndexOf( getReadingURL('') ) > -1
+                       && ajaxSettings.type == 'POST' && jqXHR.status == 403 ) {
+                         var errobj = jQuery.parseJSON( jqXHR.responseText );
+                         $('#reading_status').append( '<p class="error">Error: ' + errobj.error + '</p>' );
+                 }
+                 $(event.target).parent().find('.ui-button').button("enable");
+         });
+       } else {
+               $('#reading-form').hide();
        }
-  }).ajaxError( function(event, jqXHR, ajaxSettings, thrownError) {
-      if( ajaxSettings.url.lastIndexOf( getReadingURL('') ) > -1
-       && ajaxSettings.type == 'POST' && jqXHR.status == 403 ) {
-         var errobj = jQuery.parseJSON( jqXHR.responseText );
-          $('#reading_status').append( '<p class="error">Error: ' + errobj.error + '</p>' );
-      }
-         $(event.target).parent().find('.ui-button').button("enable");
-  });
   
 
   $('#update_workspace_button').click( function() {
index 36a0737..b34007f 100644 (file)
@@ -55,26 +55,31 @@ function toggle_checkbox( box, value ) {
 }
 
 function morphology_form ( lexlist ) {
-       $('#morphology').empty();
-       $.each( lexlist, function( idx, lex ) {
-               var morphoptions = [];
-               if( 'wordform_matchlist' in lex ) {
-                       $.each( lex['wordform_matchlist'], function( tdx, tag ) {
-                               var tagstr = stringify_wordform( tag );
-                               morphoptions.push( tagstr );
+       if( lexlist.length ) {
+               $('#morph_outer').show();
+               $('#morphology').empty();
+               $.each( lexlist, function( idx, lex ) {
+                       var morphoptions = [];
+                       if( 'wordform_matchlist' in lex ) {
+                               $.each( lex['wordform_matchlist'], function( tdx, tag ) {
+                                       var tagstr = stringify_wordform( tag );
+                                       morphoptions.push( tagstr );
+                               });
+                       }
+                       var formtag = 'morphology_' + idx;
+                       var formstr = '';
+                       if( 'form' in lex ) {
+                               formstr = stringify_wordform( lex['form'] );
+                       } 
+                       var form_morph_elements = morph_elements( 
+                               formtag, lex['string'], formstr, morphoptions );
+                       $.each( form_morph_elements, function( idx, el ) {
+                               $('#morphology').append( el );
                        });
-               }
-               var formtag = 'morphology_' + idx;
-               var formstr = '';
-               if( 'form' in lex ) {
-                       formstr = stringify_wordform( lex['form'] );
-               } 
-               var form_morph_elements = morph_elements( 
-                       formtag, lex['string'], formstr, morphoptions );
-               $.each( form_morph_elements, function( idx, el ) {
-                       $('#morphology').append( el );
                });
-       });
+       } else {
+               $('#morph_outer').hide();
+       }
 }
 
 function stringify_wordform ( tag ) {
@@ -516,39 +521,44 @@ $(document).ready(function () {
     }
   });
 
-  // function for reading form dialog should go here; for now hide the element
-  $('#reading-form').dialog({
-       autoOpen: false,
-       height: 400,
-       width: 600,
-       modal: true,
-       buttons: {
-               OK: function() {
-                       $( this ).dialog( "close" );
-               }
-       },
-       create: function() {
-       },
-       open: function() {
-        $(".ui-widget-overlay").css("background", "none");
-        $("#dialog_overlay").show();
-        $('#reading_status').empty();
-        $("#dialog_overlay").height( $("#enlargement_container").height() );
-        $("#dialog_overlay").width( $("#enlargement_container").innerWidth() );
-        $("#dialog_overlay").offset( $("#enlargement_container").offset() );
-        $("#reading-form").parent().find('.ui-button').button("enable");
-       },
-       close: function() {
-               $("#dialog_overlay").hide();
-       }
-  }).ajaxError( function(event, jqXHR, ajaxSettings, thrownError) {
-      if( ajaxSettings.url.lastIndexOf( getReadingURL('') ) > -1
-       && ajaxSettings.type == 'POST' && jqXHR.status == 403 ) {
-         var errobj = jQuery.parseJSON( jqXHR.responseText );
-          $('#reading_status').append( '<p class="error">Error: ' + errobj.error + '</p>' );
-      }
-         $(event.target).parent().find('.ui-button').button("enable");
-  });
+  // function for reading form dialog should go here; 
+  // just hide the element for now if we don't have morphology
+  if( can_morphologize ) {
+         $('#reading-form').dialog({
+               autoOpen: false,
+               width: 450,
+               modal: true,
+               buttons: {
+                       OK: function() {
+                               $( this ).dialog( "close" );
+                       }
+               },
+               create: function() {
+                       // Hide the relemmatize button since it is not allowed
+                       $('#reading_relemmatize').hide();
+               },
+               open: function() {
+                       $(".ui-widget-overlay").css("background", "none");
+                       $("#dialog_overlay").show();
+                       $('#reading_status').empty();
+                       $("#dialog_overlay").height( $("#enlargement_container").height() );
+                       $("#dialog_overlay").width( $("#enlargement_container").innerWidth() );
+                       $("#dialog_overlay").offset( $("#enlargement_container").offset() );
+               },
+               close: function() {
+                       $("#dialog_overlay").hide();
+               }
+         }).ajaxError( function(event, jqXHR, ajaxSettings, thrownError) {
+                 if( ajaxSettings.url.lastIndexOf( getReadingURL('') ) > -1
+                       && ajaxSettings.type == 'POST' && jqXHR.status == 403 ) {
+                         var errobj = jQuery.parseJSON( jqXHR.responseText );
+                         $('#reading_status').append( '<p class="error">Error: ' + errobj.error + '</p>' );
+                 }
+                 $(event.target).parent().find('.ui-button').button("enable");
+         });
+  } else {
+       $('#reading-form').hide();
+  }
   
   // Hide the unused elements
   $('#dialog-form').hide();
index d7d4642..2f5522d 100644 (file)
@@ -7,6 +7,7 @@
 // Load the text ID and the base path
 var basepath = "[% c.uri_for( '/relation/' ) %]";
 var textid = "[% textid %]";
+var can_morphologize = "[% can_morphologize %]";
 
 $(document).ready(function () {
   loadSVG('[% svg_string %]');
@@ -81,23 +82,25 @@ $(document).ready(function () {
        <div id="reading-form" title="Reading info...">
                <form id="reading_data_form" action="#">
                        <input type="hidden" name="reading_id" id="reading_id"/>
-                       <input type="checkbox" name="reading_is_nonsense" id="reading_is_nonsense"/>
-                       <label for="reading_is_nonsense">This is a nonsense word</label>
-                       <br/>
-                       <input type="checkbox" name="reading_grammar_invalid" id="reading_grammar_invalid"/>
-                       <label for="reading_grammar_invalid">This word's grammar cannot be right</label>
+                       <div class="morph">
+                               <input type="checkbox" name="reading_is_nonsense" id="reading_is_nonsense"/>
+                               <label for="reading_is_nonsense">This is a nonsense word</label>
+                               <br/>
+                               <input type="checkbox" name="reading_grammar_invalid" id="reading_grammar_invalid"/>
+                               <label for="reading_grammar_invalid">This word's grammar cannot be right</label>
+                       </div>
                        <br/><br/>
                        <!-- Morphological options go here -->
-                       <div id="normalization">
+                       <div id="normalization" class="morph">
                                <label for="reading_normal_form">Normalized form: </label>
                                <input type="text" name="reading_normal_form" id="reading_normal_form"></input>
-                               <button id="#reading_relemmatize" onclick="relemmatize(); return false;">Re-lemmatize</button>
+                               <button id="reading_relemmatize" onclick="relemmatize(); return false;">Re-lemmatize</button>
                        </div>
                        <div id="relemmatize_pending">
                                <img src="[% c.uri_for('/images/ajax-loader.gif') %]"/>
                        </div>
                        <br/><br/>
-                       <div id="morph_outer">
+                       <div id="morph_outer" class="morph">
                                <label>Lemma / part of speech:</label><br/>
                                <div id="morphology"></div>
                        </div>