Extending Zymonic with polymorphism (subclassing): Difference between revisions

From Zymonic
Content added Content deleted
(Created page with "=Extending Zymonic with polymorphism (sub-classing)= In general sub-classing is done by copying the existing class e.g. Zymonic/Field.pm into the appropriate sub-directory (F...")
 
 
(One intermediate revision by the same user not shown)
Line 3: Line 3:
In general sub-classing is done by copying the existing class e.g. Zymonic/Field.pm into the appropriate sub-directory (Field) with a new name e.g. Zymonic/Field/MySubClass.pm, changing the package name, the content of the POD and removing all the methods from the original file apart from any you intend to modify.
In general sub-classing is done by copying the existing class e.g. Zymonic/Field.pm into the appropriate sub-directory (Field) with a new name e.g. Zymonic/Field/MySubClass.pm, changing the package name, the content of the POD and removing all the methods from the original file apart from any you intend to modify.


Where a class has user interface elements then they may well have javascript and XSL attached to them which can also be sub-classed.
However, there are some cases that warrant further discussion:


Javascript is subclassed in almost identical manner to the Perl, but these files can be found in javascript/Zymonic - for our field example we would create javascript/Zymonic/Field/05_MySubClass.js - the 'number' in the name can be used to force load order (which is sometimes critical for JS). If doing this then the new JS must be brought in as an include by the Perl - Zymonic::Field::MySubClass::script_includes:
[[FieldFillCalculation]]

<code>
sub script_includes
{
my $self = shift;

return ( $self->SUPER::script_includes(), '/Zymonic/Field/01_MySubClass.js' );
}
</code>

If the HTML needs changing then the XSL must also be extended; generally this can be done by adding XSL that has a specific template match on 'subtype' e.g.

<code>
<xsl:template match="*[@type='FieldFillCalculation' and @subtype='SubForm']">
</code>

Including the XSL is currently a bit of a work in progress... Historically it required a change to at least one of the already used XSL templates to add an 'import' line that imported the XSL associated with the object e.g. in stylesheets/ZymonicField.xsl there is:

<code>
<!-- import subclassed fields -->
<xsl:include href="Field/Choice.xsl" />
<xsl:include href="Field/DateTime.xsl" />
<xsl:include href="Field/File.xsl" />
<xsl:include href="Field/Glob.xsl" />
<xsl:include href="Field/HTML.xsl" />
<xsl:include href="Field/LinkedField.xsl" />
<xsl:include href="Field/MultipleChoice.xsl"/>
<xsl:include href="Field/MultipleChoiceLinkedField.xsl" />
<xsl:include href="Field/MultipleValue.xsl"/>
<xsl:include href="Field/PasswordCapture.xsl" />
<xsl:include href="Field/SubFilter.xsl" />
<xsl:include href="Field/SubForm.xsl" />
<xsl:include href="Field/ZymonicXML.xsl" />
</code>

However, recently we added a mechanism for XML authors to add XSL that would be added to the 'main' (and block combined) XSL for the system by the Installer / config build:

<code>
<!-- IncludeXSL -->
<xs:complexType name="IncludeXSL">
<xs:annotation>
<xs:documentation>Used to add XSL to the Main and Block XSL</xs:documentation>
</xs:annotation>
<xs:choice maxOccurs="unbounded">
<xs:element minOccurs="1" maxOccurs="1" ref="ZName" />
<xs:element minOccurs="1" maxOccurs="1" type="xs:string" name="XSLhref" />
</xs:choice>
</xs:complexType>
</code>

I believe it should be possible for new custom field classes to leverage this functionality - but it will require them to trigger code during config build.

TODO - replace the above once its actually been tried!

Latest revision as of 11:41, 10 September 2019

Extending Zymonic with polymorphism (sub-classing)[edit]

In general sub-classing is done by copying the existing class e.g. Zymonic/Field.pm into the appropriate sub-directory (Field) with a new name e.g. Zymonic/Field/MySubClass.pm, changing the package name, the content of the POD and removing all the methods from the original file apart from any you intend to modify.

Where a class has user interface elements then they may well have javascript and XSL attached to them which can also be sub-classed.

Javascript is subclassed in almost identical manner to the Perl, but these files can be found in javascript/Zymonic - for our field example we would create javascript/Zymonic/Field/05_MySubClass.js - the 'number' in the name can be used to force load order (which is sometimes critical for JS). If doing this then the new JS must be brought in as an include by the Perl - Zymonic::Field::MySubClass::script_includes:

sub script_includes {

   my $self = shift;
   return ( $self->SUPER::script_includes(), '/Zymonic/Field/01_MySubClass.js' );

}

If the HTML needs changing then the XSL must also be extended; generally this can be done by adding XSL that has a specific template match on 'subtype' e.g.

 <xsl:template match="*[@type='FieldFillCalculation' and @subtype='SubForm']">

Including the XSL is currently a bit of a work in progress... Historically it required a change to at least one of the already used XSL templates to add an 'import' line that imported the XSL associated with the object e.g. in stylesheets/ZymonicField.xsl there is:

 <xsl:include href="Field/Choice.xsl" />
 <xsl:include href="Field/DateTime.xsl" />
 <xsl:include href="Field/File.xsl" />
 <xsl:include href="Field/Glob.xsl" />
 <xsl:include href="Field/HTML.xsl" />
 <xsl:include href="Field/LinkedField.xsl" />
 <xsl:include href="Field/MultipleChoice.xsl"/>
 <xsl:include href="Field/MultipleChoiceLinkedField.xsl" />
 <xsl:include href="Field/MultipleValue.xsl"/>
 <xsl:include href="Field/PasswordCapture.xsl" />
 <xsl:include href="Field/SubFilter.xsl" />
 <xsl:include href="Field/SubForm.xsl" />
 <xsl:include href="Field/ZymonicXML.xsl" />

However, recently we added a mechanism for XML authors to add XSL that would be added to the 'main' (and block combined) XSL for the system by the Installer / config build:

 <xs:complexType name="IncludeXSL">
   <xs:annotation>
     <xs:documentation>Used to add XSL to the Main and Block XSL</xs:documentation>
   </xs:annotation>
   <xs:choice maxOccurs="unbounded">
     <xs:element minOccurs="1" maxOccurs="1" ref="ZName" />
     <xs:element minOccurs="1" maxOccurs="1" type="xs:string" name="XSLhref" />
   </xs:choice>
 </xs:complexType>

I believe it should be possible for new custom field classes to leverage this functionality - but it will require them to trigger code during config build.

TODO - replace the above once its actually been tried!