Add new MapPoint code for geolocation, Thingy searching and indexing and a macro for rendering thing data outside of the Thingy.
This commit is contained in:
parent
944c76040a
commit
61534779d5
24 changed files with 1442 additions and 176 deletions
|
|
@ -18,6 +18,9 @@ use strict;
|
|||
use Tie::IxHash;
|
||||
use base 'WebGUI::Asset';
|
||||
use WebGUI::Utility;
|
||||
use Geo::Coder::Googlev3;
|
||||
use Data::Dumper;
|
||||
|
||||
|
||||
# To get an installer for your wobject, add the Installable AssetAspect
|
||||
# See WebGUI::AssetAspect::Installable and sbin/installClass.pl for more
|
||||
|
|
@ -143,6 +146,12 @@ sub definition {
|
|||
hoverHelp => $i18n->get("storageIdPhoto description"),
|
||||
noFormPost => 1,
|
||||
},
|
||||
isGeocoded => {
|
||||
fieldType => "yesNo",
|
||||
tab => "properties",
|
||||
label => $i18n->get("isGeocoded label"),
|
||||
hoverHelp => $i18n->get("isGeocoded description"),
|
||||
},
|
||||
userDefined1 => {
|
||||
fieldType => "hidden",
|
||||
},
|
||||
|
|
@ -159,6 +168,7 @@ sub definition {
|
|||
fieldType => "hidden",
|
||||
},
|
||||
);
|
||||
|
||||
push @{$definition}, {
|
||||
assetName => $i18n->get('assetName'),
|
||||
icon => 'mappoint.png',
|
||||
|
|
@ -212,6 +222,7 @@ AT LEAST the following keys:
|
|||
title - The title of the point
|
||||
content - HTML content to show details about the point
|
||||
url - The URL of the point
|
||||
userDefined1-5 - The userDefined fields
|
||||
|
||||
The following keys are optional
|
||||
|
||||
|
|
@ -227,7 +238,7 @@ sub getMapInfo {
|
|||
# Get asset properties
|
||||
$var->{ url } = $self->getUrl;
|
||||
$var->{ assetId } = $self->getId;
|
||||
my @keys = qw( latitude longitude title );
|
||||
my @keys = qw( latitude longitude title userDefined1 userDefined2 userDefined3 userDefined4 userDefined5 isGeocoded );
|
||||
for my $key ( @keys ) {
|
||||
$var->{ $key } = $self->get( $key );
|
||||
}
|
||||
|
|
@ -274,6 +285,15 @@ sub getTemplateVarsEditForm {
|
|||
my $session = $self->session;
|
||||
my $var = $self->getTemplateVars;
|
||||
|
||||
my $parent = $self->getParent;
|
||||
#If it's a new point, we have to get the parent from the url
|
||||
unless ($parent) {
|
||||
my $url = $session->url->page;
|
||||
$parent = WebGUI::Asset->newByUrl($session,$url);
|
||||
}
|
||||
|
||||
$var->{'can_edit_map'} = $parent->canEdit;
|
||||
|
||||
$var->{ form_header }
|
||||
= WebGUI::Form::formHeader( $session )
|
||||
. WebGUI::Form::hidden( $session, {
|
||||
|
|
@ -323,8 +343,25 @@ sub getTemplateVarsEditForm {
|
|||
name => "synopsis",
|
||||
value => $self->get("synopsis"),
|
||||
resizable => 0,
|
||||
} );
|
||||
} );
|
||||
|
||||
#Only allow people who can edit the parent to change isHidden
|
||||
if($var->{'can_edit_map'}) {
|
||||
my $isHidden = (defined $self->get("isHidden")) ? $self->get("isHidden") : 1;
|
||||
$var->{ "form_isHidden" }
|
||||
= WebGUI::Form::yesNo( $session, {
|
||||
name => "isHidden",
|
||||
value => $isHidden,
|
||||
} );
|
||||
}
|
||||
|
||||
my $isGeocoded = ( $self->getId ) ? $self->get("isGeocoded") : 1;
|
||||
$var->{"form_isGeocoded"}
|
||||
= WebGUI::Form::checkbox( $session, {
|
||||
name => "isGeocoded",
|
||||
value => 1,
|
||||
checked => $isGeocoded
|
||||
} );
|
||||
# Fix storageIdPhoto because scripts do not get executed in ajax requests
|
||||
$var->{ "form_storageIdPhoto" }
|
||||
= '<input type="file" name="storageIdPhoto" />';
|
||||
|
|
@ -339,6 +376,35 @@ sub getTemplateVarsEditForm {
|
|||
|
||||
#-------------------------------------------------------------------
|
||||
|
||||
=head2 indexContent ( )
|
||||
|
||||
Indexing the content of attachments and user defined fields. See WebGUI::Asset::indexContent() for additonal details.
|
||||
|
||||
=cut
|
||||
|
||||
sub indexContent {
|
||||
my $self = shift;
|
||||
my $indexer = $self->SUPER::indexContent;
|
||||
$indexer->addKeywords($self->get("website"));
|
||||
$indexer->addKeywords($self->get("address1"));
|
||||
$indexer->addKeywords($self->get("address2"));
|
||||
$indexer->addKeywords($self->get("city"));
|
||||
$indexer->addKeywords($self->get("region"));
|
||||
$indexer->addKeywords($self->get("zipCode"));
|
||||
$indexer->addKeywords($self->get("country"));
|
||||
$indexer->addKeywords($self->get("phone"));
|
||||
$indexer->addKeywords($self->get("fax"));
|
||||
$indexer->addKeywords($self->get("email"));
|
||||
$indexer->addKeywords($self->get("userDefined1"));
|
||||
$indexer->addKeywords($self->get("userDefined2"));
|
||||
$indexer->addKeywords($self->get("userDefined3"));
|
||||
$indexer->addKeywords($self->get("userDefined4"));
|
||||
$indexer->addKeywords($self->get("userDefined5"));
|
||||
return $indexer;
|
||||
}
|
||||
|
||||
#-------------------------------------------------------------------
|
||||
|
||||
=head2 processAjaxEditForm ( )
|
||||
|
||||
Process the Ajax Edit Form from the Map. If any errors occur, return
|
||||
|
|
@ -367,6 +433,29 @@ sub processAjaxEditForm {
|
|||
$prop->{ synopsis } = $form->get('synopsis');
|
||||
$prop->{ url } = $session->url->urlize( $self->getParent->getUrl . '/' . $prop->{title} );
|
||||
$prop->{ ownerUserId } = $form->get('ownerUserId') || $session->user->userId;
|
||||
#Only users who can edit the map can set this property
|
||||
if($self->getParent->canEdit) {
|
||||
$prop->{ isHidden } = $form->get('isHidden');
|
||||
}
|
||||
$prop->{isGeocoded } = $form->get('isGeocoded') || 0;
|
||||
if($prop->{isGeocoded} &&
|
||||
(
|
||||
( $form->get("address1") ne $self->get("address1") )
|
||||
|| ( $form->get("address2") ne $self->get("address2") )
|
||||
|| ( $form->get("city") ne $self->get("city") )
|
||||
|| ( $form->get("region") ne $self->get("region") )
|
||||
|| ( $form->get("zipCode") ne $self->get("zipCode") )
|
||||
|| ( $form->get("country") ne $self->get("country") )
|
||||
)
|
||||
) {
|
||||
my $geocoder = Geo::Coder::Googlev3->new;
|
||||
my $address_str = $form->get("address1");
|
||||
$address_str .= " ".$form->get("address2") if($form->get("address2"));
|
||||
$address_str .= ", ".$form->get("city").", ".$form->get("region").", ".$form->get("zipCode").", ".$form->get("country");
|
||||
my $location = $geocoder->geocode( location => $address_str );
|
||||
$prop->{latitude } = $location->{geometry}->{location}->{lat};
|
||||
$prop->{longitude} = $location->{geometry}->{location}->{lng};
|
||||
}
|
||||
|
||||
$self->update( $prop );
|
||||
|
||||
|
|
@ -420,6 +509,7 @@ sub www_view {
|
|||
return "redirect";
|
||||
}
|
||||
|
||||
|
||||
1;
|
||||
|
||||
#vim:ft=perl
|
||||
|
|
|
|||
|
|
@ -18,6 +18,7 @@ use WebGUI::International;
|
|||
use WebGUI::Utility;
|
||||
use HTML::Entities qw(encode_entities);
|
||||
use base 'WebGUI::Asset::Wobject';
|
||||
use Data::Dumper;
|
||||
|
||||
# To get an installer for your wobject, add the Installable AssetAspect
|
||||
# See WebGUI::AssetAspect::Installable and sbin/installClass.pl for more
|
||||
|
|
@ -387,7 +388,9 @@ sub view {
|
|||
google.setOnLoadCallback( function() {
|
||||
var mapId = "%s";
|
||||
var mapUrl = "%s";
|
||||
var map = new GMap2( document.getElementById("map_" + mapId) );
|
||||
var element = document.getElementById("map_" + mapId);
|
||||
var map = new GMap2( element );
|
||||
element.mapObject = map;
|
||||
map.url = mapUrl;
|
||||
map.assetId = mapId;
|
||||
map.setCenter(new GLatLng(%s, %s), %s);
|
||||
|
|
@ -395,6 +398,10 @@ sub view {
|
|||
map.extrasUrl = "%s";
|
||||
|
||||
var markermanager = new MarkerManager(map, {trackMarkers: true});
|
||||
map.markermanager = markermanager;
|
||||
map.fancyClickHandler = null;
|
||||
map.panOnClick = true;
|
||||
map.clickToEdit = false;
|
||||
ENDHTML
|
||||
|
||||
|
||||
|
|
@ -408,9 +415,9 @@ ENDHTML
|
|||
for my $pointId ( @{$pointIds} ) {
|
||||
my $point = WebGUI::Asset->newByDynamicClass( $session, $pointId );
|
||||
next unless $point;
|
||||
$mapHtml .= sprintf ' points.push(%s);'."\n",
|
||||
JSON->new->encode($point->getMapInfo),
|
||||
;
|
||||
my $buffer = JSON->new->encode( $point->getMapInfo );
|
||||
|
||||
$mapHtml .= sprintf ' points.push(%s);'."\n", $buffer;
|
||||
|
||||
push @{$var->{ mapPoints }}, $point->getTemplateVars;
|
||||
}
|
||||
|
|
@ -432,11 +439,11 @@ ENDHTML
|
|||
}
|
||||
|
||||
# Script to control addPoint and setPoint buttons
|
||||
$mapHtml .= <<'ENDHTML';
|
||||
$mapHtml .= sprintf <<'ENDHTML', $self->getUrl;
|
||||
if ( document.getElementById( "setCenter_" + mapId ) ) {
|
||||
var button = document.getElementById( "setCenter_" + mapId );
|
||||
GEvent.addDomListener( button, "click", function () {
|
||||
WebGUI.Map.setCenter( map );
|
||||
WebGUI.Map.setCenter( map, '%s' );
|
||||
} );
|
||||
}
|
||||
if ( document.getElementById( "addPoint_" + mapId ) ) {
|
||||
|
|
|
|||
|
|
@ -213,30 +213,31 @@ sub view {
|
|||
);
|
||||
|
||||
my @results = ();
|
||||
foreach my $data (@{$p->getPageData}) {
|
||||
next unless (
|
||||
ENTRY: foreach my $data (@{$p->getPageData}) {
|
||||
next ENTRY unless (
|
||||
$user->userId eq $data->{ownerUserId}
|
||||
|| $user->isInGroup($data->{groupIdView})
|
||||
|| $user->isInGroup($data->{groupIdEdit})
|
||||
);
|
||||
|
||||
my $asset = WebGUI::Asset->new($session, $data->{assetId}, $data->{className});
|
||||
if (defined $asset) {
|
||||
my $properties = $asset->get;
|
||||
if ( $self->get("useContainers") && $asset->getContainer->canView ) {
|
||||
$properties->{url} = $asset->isa('WebGUI::Asset::Post::Thread') ? $asset->getCSLinkUrl()
|
||||
: $asset->getContainer->get("url");
|
||||
}
|
||||
#Add highlighting
|
||||
$properties->{'title' } = $hl->highlight($properties->{title} || '');
|
||||
$properties->{'title_nohighlight' } = $properties->{title};
|
||||
my $synopsis = $data->{'synopsis'} || '';
|
||||
WebGUI::Macro::process($self->session, \$synopsis);
|
||||
$properties->{'synopsis' } = $hl->highlight($synopsis);
|
||||
$properties->{'synopsis_nohighlight'} = $synopsis;
|
||||
push(@results, $properties);
|
||||
$var{results_found} = 1;
|
||||
}
|
||||
next ENTRY unless defined $asset;
|
||||
my $properties = $asset->get;
|
||||
##Overlay the asset properties with the original data to handle sub-entries for assets
|
||||
$properties = { %{ $properties }, %{ $data} };
|
||||
if ( $self->get("useContainers") && $asset->getContainer->canView ) {
|
||||
$properties->{url} = $asset->isa('WebGUI::Asset::Post::Thread') ? $asset->getCSLinkUrl()
|
||||
: $asset->getContainer->get("url");
|
||||
}
|
||||
#Add highlighting
|
||||
$properties->{'title' } = $hl->highlight($properties->{title} || '');
|
||||
$properties->{'title_nohighlight' } = $properties->{title};
|
||||
my $synopsis = $properties->{'synopsis'} || '';
|
||||
WebGUI::Macro::process($self->session, \$synopsis);
|
||||
$properties->{'synopsis' } = $hl->highlight($synopsis);
|
||||
$properties->{'synopsis_nohighlight'} = $synopsis;
|
||||
push(@results, $properties);
|
||||
$var{results_found} = 1;
|
||||
}
|
||||
|
||||
$var{result_set} = \@results;
|
||||
|
|
|
|||
|
|
@ -279,6 +279,24 @@ sub definition {
|
|||
}
|
||||
|
||||
|
||||
#-------------------------------------------------------------------
|
||||
|
||||
=head2 deleteThingIndex ( $thingId )
|
||||
|
||||
Remove the entry about this Thing from the database, and for any rows for it that are indexed as well.
|
||||
|
||||
=head3 $thingId
|
||||
|
||||
The GUID of the Thing, used to pick out this record in the database.
|
||||
|
||||
=cut
|
||||
|
||||
sub deleteThingIndex {
|
||||
my $self = shift;
|
||||
my $thingId = shift;
|
||||
$self->session->db->write(q|delete from assetIndex where assetId=? and subId like CONCAT(?,'%')|,[$self->getId, $thingId]);
|
||||
}
|
||||
|
||||
#-------------------------------------------------------------------
|
||||
|
||||
=head2 duplicate ( )
|
||||
|
|
@ -367,6 +385,8 @@ sub duplicateThing {
|
|||
$self->addField($field,0);
|
||||
}
|
||||
|
||||
$thingProperties->{thingId} = $newThingId;
|
||||
$self->indexThing($thingProperties);
|
||||
return $newThingId;
|
||||
|
||||
}
|
||||
|
|
@ -418,6 +438,7 @@ sub deleteField {
|
|||
$db->write("ALTER TABLE ".$db->dbh->quote_identifier("Thingy_".$thingId)." DROP "
|
||||
.$db->dbh->quote_identifier("field_".$fieldId));
|
||||
}
|
||||
$self->reindexThings;
|
||||
$error->info("Deleted field: $fieldId in thing: $thingId.");
|
||||
return undef;
|
||||
}
|
||||
|
|
@ -468,6 +489,7 @@ sub copyThingData {
|
|||
}
|
||||
##Update the copy
|
||||
$self->setCollateral("Thingy_".$thingId, "thingDataId", $origCollateral, 0, 0);
|
||||
$self->indexThingData($thingId, $origCollateral);
|
||||
|
||||
return undef;
|
||||
}
|
||||
|
|
@ -522,11 +544,30 @@ sub deleteThingData {
|
|||
$storage->delete;
|
||||
}
|
||||
|
||||
$self->deleteThingDataIndex($thingDataId);
|
||||
return undef;
|
||||
}
|
||||
|
||||
#-------------------------------------------------------------------
|
||||
|
||||
=head2 deleteThingDataIndex ( $thingDataId )
|
||||
|
||||
Remove the entry about this Thing from the database, and for any rows for it that are indexed as well.
|
||||
|
||||
=head3 $thingDataId
|
||||
|
||||
The GUID of the thingData to remove, used to pick out this record in the database.
|
||||
|
||||
=cut
|
||||
|
||||
sub deleteThingDataIndex {
|
||||
my $self = shift;
|
||||
my $thingDataId = shift;
|
||||
$self->session->db->write(q|delete from assetIndex where assetId=? and subId like CONCAT('%-',?)|,[$self->getId, $thingDataId]);
|
||||
}
|
||||
|
||||
#-------------------------------------------------------------------
|
||||
|
||||
=head2 deleteThing ( thingId )
|
||||
|
||||
Deletes a Thing and its fields from Collateral and drops the things table.
|
||||
|
|
@ -549,6 +590,7 @@ sub deleteThing {
|
|||
$session->db->write("drop table if exists ".$session->db->dbh->quote_identifier("Thingy_".$thingId));
|
||||
|
||||
$error->info("Deleted thing: $thingId.");
|
||||
$self->deleteThingIndex($thingId);
|
||||
return undef;
|
||||
}
|
||||
|
||||
|
|
@ -636,6 +678,7 @@ sub editThingDataSave {
|
|||
return ('', \@errors);
|
||||
}
|
||||
$newThingDataId = $self->setCollateral("Thingy_".$thingId,"thingDataId",\%thingData,0,0);
|
||||
$self->indexThingData($thingId, \%thingData);
|
||||
|
||||
# trigger workflow
|
||||
if($thingDataId eq "new"){
|
||||
|
|
@ -697,6 +740,7 @@ sub field_isa {
|
|||
my $session = $self->session;
|
||||
my $fieldType = shift;
|
||||
my $isa = shift;
|
||||
$fieldType = ucfirst $fieldType;
|
||||
my $control = eval { WebGUI::Pluggable::instanciate("WebGUI::Form::".$fieldType, "new", [ $session, () ]) };
|
||||
return ($control && $control->isa($isa));
|
||||
}
|
||||
|
|
@ -1286,6 +1330,7 @@ sub getViewThingVars {
|
|||
);
|
||||
push(@viewScreenTitleFields,$value) if ($field{viewScreenTitle});
|
||||
push(@field_loop, { map {("field_".$_ => $fieldProperties{$_})} keys(%fieldProperties) });
|
||||
$var->{ $field{label} } = $value;
|
||||
}
|
||||
$var->{viewScreenTitle} = join(" ",@viewScreenTitleFields);
|
||||
$var->{field_loop} = \@field_loop;
|
||||
|
|
@ -1398,6 +1443,7 @@ sub importAssetCollateralData {
|
|||
# add new thing
|
||||
$self->addThing($thing,1);
|
||||
}
|
||||
$self->indexThing($thing);
|
||||
}
|
||||
# delete deleted things
|
||||
my $thingsInDatabase = $self->getThings;
|
||||
|
|
@ -1439,6 +1485,126 @@ sub importAssetCollateralData {
|
|||
}
|
||||
|
||||
|
||||
#-------------------------------------------------------------------
|
||||
|
||||
=head2 indexContent ( )
|
||||
|
||||
Extend the base class to handle reindexing every Thing, and every row in every Thing. We have
|
||||
to do a complete rework because the URL may have changed, and that affects everything that has
|
||||
been inserted into the AssetIndex.
|
||||
|
||||
=cut
|
||||
|
||||
sub indexContent {
|
||||
my ($self) = @_;
|
||||
my $session = $self->session;
|
||||
$self->SUPER::indexContent();
|
||||
$self->reindexThings;
|
||||
}
|
||||
|
||||
|
||||
#-------------------------------------------------------------------
|
||||
|
||||
=head2 indexThing ( $thing )
|
||||
|
||||
Add an entry about this Thing into the AssetIndex so it can be found for searches.
|
||||
|
||||
=head3 $thing
|
||||
|
||||
A hashref of Thing properties, as returned by getThing
|
||||
|
||||
=cut
|
||||
|
||||
sub indexThing {
|
||||
my ($self, $thing) = @_;
|
||||
return unless $thing;
|
||||
my $index = WebGUI::Search::Index->new($self);
|
||||
$index->addRecord(
|
||||
url => $self->getUrl($self->getThingUrl($thing)),
|
||||
groupIdView => $thing->{groupIdView},
|
||||
title => $thing->{label},
|
||||
subId => $thing->{thingId},
|
||||
keywords => join(' ', @{$thing}{qw/label editScreenTitle editInstructions searchScreenTitle searchDescription/}),
|
||||
);
|
||||
##Easy update of all thingData fields for this thing. This is in lieu of deleting all records
|
||||
##And rebuilding them all.
|
||||
$self->session->db->write(q|update assetIndex set title=?, groupIdView=? where assetId=? and subId like CONCAT(?, '%')|, [$thing->{label}, $thing->{groupIdView}, $self->getId, $thing->{thingId}]);
|
||||
}
|
||||
|
||||
|
||||
#-------------------------------------------------------------------
|
||||
|
||||
=head2 indexThingData ( $thingId, $thingData )
|
||||
|
||||
Add an entry about a row from this Thing into the AssetIndex so it can be found for searches.
|
||||
|
||||
=head3 $thingId
|
||||
|
||||
The GUID for a Thing.
|
||||
|
||||
=head3 $thingData
|
||||
|
||||
A hashref of ThingData properties
|
||||
|
||||
=cut
|
||||
|
||||
sub indexThingData {
|
||||
my ($self, $thingId, $thingData) = @_;
|
||||
my $session = $self->session;
|
||||
return unless $thingId;
|
||||
my $thing = $self->getThing($thingId);
|
||||
my $index = WebGUI::Search::Index->new($self);
|
||||
my $keywords;
|
||||
##Get the Thingy's fields
|
||||
my $fields = $session->db->read('select * from Thingy_fields where assetId = ? and thingId = ?',
|
||||
[$self->getId, $thingId]);
|
||||
##Walk the fields
|
||||
my @viewScreenTitleFields = ();
|
||||
FIELD: while (my %field = $fields->hash) {
|
||||
my $fieldName = 'field_'.$field{fieldId};
|
||||
$field{value} = $thingData->{$fieldName} || $field{defaultValue};
|
||||
my $subkeywords = '';
|
||||
my $value = '';
|
||||
if ($self->field_isa($field{fieldType}, 'WebGUI::Form::File')) {
|
||||
my $storage = WebGUI::Storage->get($session, $field{value});
|
||||
if ($storage) {
|
||||
foreach my $file (@{$storage->getFiles()}) {
|
||||
$subkeywords = $index->getKeywordsForFile($storage->getPath($file));
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
$value = $self->getFieldValue($field{value}, \%field);
|
||||
##If it's a file type, then get keywords from the file.
|
||||
##Accumulate keywords
|
||||
$subkeywords = $value;
|
||||
}
|
||||
if ($value && $field{viewScreenTitle}) {
|
||||
push @viewScreenTitleFields, $value;
|
||||
}
|
||||
##We don't index date fields, since they're unix epochs and they'd be different for everyone based on timezone.
|
||||
next FIELD if $field{fieldType} eq 'date'
|
||||
|| $field{fieldType} eq 'datetime'
|
||||
|| $field{fieldType} eq 'time';
|
||||
##Don't show what shouldn't be shown
|
||||
next FIELD unless $field{displayInSearch};
|
||||
$keywords = join ' ', $keywords, $subkeywords;
|
||||
}
|
||||
return unless $keywords; ##No sense indexing nothing;
|
||||
my $title = join('', @viewScreenTitleFields)
|
||||
|| $thing->{label}
|
||||
|| $self->getTitle;
|
||||
$index->addRecord(
|
||||
assetId => $self->getId,
|
||||
url => $self->getUrl('func=viewThingData;thingId='. $thing->{thingId} . ';thingDataId='. $thingData->{thingDataId}),
|
||||
groupIdView => $thing->{groupIdView},
|
||||
title => $title,
|
||||
subId => $thing->{thingId} . '-' . $thingData->{thingDataId},
|
||||
keywords => $keywords,
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
#-------------------------------------------------------------------
|
||||
|
||||
=head2 prepareView ( )
|
||||
|
|
@ -1487,6 +1653,30 @@ sub purge {
|
|||
return $self->SUPER::purge;
|
||||
}
|
||||
|
||||
#-------------------------------------------------------------------
|
||||
|
||||
=head2 reindexThings ( )
|
||||
|
||||
Reindex every Thing, and every row in every Thing.
|
||||
|
||||
=cut
|
||||
|
||||
sub reindexThings {
|
||||
my ($self) = @_;
|
||||
my $session = $self->session;
|
||||
my $things = $self->getThings;
|
||||
THING: while (my $thing = $things->hashRef) {
|
||||
$self->deleteThingIndex($thing->{thingId});
|
||||
$self->indexThing($thing);
|
||||
my $sth = $session->db->read('select * from '. $session->db->dbh->quote_identifier('Thingy_'.$thing->{thingId}));
|
||||
while (my $thingData = $sth->hashRef) {
|
||||
$self->indexThingData($thing->{thingId}, $thingData);
|
||||
}
|
||||
$sth->finish;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#-------------------------------------------------------------------
|
||||
|
||||
=head2 triggerWorkflow ( workflowId, thingId, thingDataId )
|
||||
|
|
@ -2222,44 +2412,44 @@ sub www_editThingSave {
|
|||
|
||||
my $self = shift;
|
||||
return $self->session->privilege->insufficient() unless $self->canEdit;
|
||||
my $form = $self->session->form;
|
||||
my ($thingId, $fields);
|
||||
$thingId = $self->session->form->process("thingId");
|
||||
|
||||
$fields = $self->getFields($thingId);
|
||||
my $form = $self->session->form;
|
||||
my $thingId = $self->session->form->process("thingId");
|
||||
my $fields = $self->getFields($thingId);
|
||||
|
||||
my $thing = {
|
||||
thingId => $thingId,
|
||||
label => $form->process("label"),
|
||||
editScreenTitle => $form->process("editScreenTitle"),
|
||||
editInstructions => $form->process("editInstructions"),
|
||||
groupIdAdd => $form->process("groupIdAdd"),
|
||||
groupIdEdit => $form->process("groupIdEdit"),
|
||||
saveButtonLabel => $form->process("saveButtonLabel"),
|
||||
afterSave => $form->process("afterSave"),
|
||||
editTemplateId => $form->process("editTemplateId") || 1,
|
||||
onAddWorkflowId => $form->process("onAddWorkflowId"),
|
||||
onEditWorkflowId => $form->process("onEditWorkflowId"),
|
||||
onDeleteWorkflowId => $form->process("onDeleteWorkflowId"),
|
||||
groupIdView => $form->process("groupIdView"),
|
||||
viewTemplateId => $form->process("viewTemplateId") || 1,
|
||||
defaultView => $form->process("defaultView"),
|
||||
searchScreenTitle => $form->process("searchScreenTitle"),
|
||||
searchDescription => $form->process("searchDescription"),
|
||||
groupIdSearch => $form->process("groupIdSearch"),
|
||||
groupIdImport => $form->process("groupIdImport"),
|
||||
groupIdExport => $form->process("groupIdExport"),
|
||||
searchTemplateId => $form->process("searchTemplateId") || 1,
|
||||
thingsPerPage => $form->process("thingsPerPage") || 25,
|
||||
sortBy => $form->process("sortBy") || '',
|
||||
exportMetaData => $form->process("exportMetaData") || '',
|
||||
maxEntriesPerUser => $form->process("maxEntriesPerUser") || '',
|
||||
};
|
||||
$self->setCollateral("Thingy_things", "thingId", $thing, 0, 1);
|
||||
|
||||
if($fields->rows < 1){
|
||||
$self->session->log->warn("Thing failed to create because it had no fields");
|
||||
my $i18n = WebGUI::International->new($self->session, "Asset_Thingy");
|
||||
return $self->www_editThing($i18n->get("thing must have fields"));
|
||||
}
|
||||
$self->setCollateral("Thingy_things","thingId",{
|
||||
thingId=>$thingId,
|
||||
label=>$form->process("label"),
|
||||
editScreenTitle=>$form->process("editScreenTitle"),
|
||||
editInstructions=>$form->process("editInstructions"),
|
||||
groupIdAdd=>$form->process("groupIdAdd"),
|
||||
groupIdEdit=>$form->process("groupIdEdit"),
|
||||
saveButtonLabel=>$form->process("saveButtonLabel"),
|
||||
afterSave=>$form->process("afterSave"),
|
||||
editTemplateId=>$form->process("editTemplateId") || 1,
|
||||
onAddWorkflowId=>$form->process("onAddWorkflowId"),
|
||||
onEditWorkflowId=>$form->process("onEditWorkflowId"),
|
||||
onDeleteWorkflowId=>$form->process("onDeleteWorkflowId"),
|
||||
groupIdView=>$form->process("groupIdView"),
|
||||
viewTemplateId=>$form->process("viewTemplateId") || 1,
|
||||
defaultView=>$form->process("defaultView"),
|
||||
searchScreenTitle=>$form->process("searchScreenTitle"),
|
||||
searchDescription=>$form->process("searchDescription"),
|
||||
groupIdSearch=>$form->process("groupIdSearch"),
|
||||
groupIdImport=>$form->process("groupIdImport"),
|
||||
groupIdExport=>$form->process("groupIdExport"),
|
||||
searchTemplateId=>$form->process("searchTemplateId") || 1,
|
||||
thingsPerPage=>$form->process("thingsPerPage") || 25,
|
||||
sortBy=>$form->process("sortBy") || '',
|
||||
exportMetaData=>$form->process("exportMetaData") || '',
|
||||
maxEntriesPerUser=>$form->process("maxEntriesPerUser") || '',
|
||||
},0,1);
|
||||
|
||||
while (my $field = $fields->hashRef) {
|
||||
my $display = $self->session->form->process("display_".$field->{fieldId}) || 0;
|
||||
|
|
@ -2269,6 +2459,7 @@ sub www_editThingSave {
|
|||
|
||||
$self->session->db->write("update Thingy_fields set display = ?, viewScreenTitle = ?, displayinSearch = ?, searchIn = ? where fieldId = ? and thingId = ?",[$display, $viewScreenTitle, $displayInSearch, $searchIn, $field->{fieldId}, $thingId]);
|
||||
}
|
||||
$self->indexThing($thing);
|
||||
return $self->www_manage;
|
||||
}
|
||||
#-------------------------------------------------------------------
|
||||
|
|
@ -3135,13 +3326,7 @@ sub www_manage {
|
|||
'thing_searchUrl' => $session->url->append($url, 'func=search;thingId='.$thing->{thingId}),
|
||||
);
|
||||
# set the url for the view icon to the things default view
|
||||
my $viewParams;
|
||||
if ($thing->{defaultView} eq "addThing") {
|
||||
$viewParams = 'func=editThingData;thingId='.$thing->{thingId}.';thingDataId=new';
|
||||
}
|
||||
else{
|
||||
$viewParams = 'func=search;thingId='.$thing->{thingId};
|
||||
}
|
||||
my $viewParams = $self->getThingUrl($thing);
|
||||
$templateVars{'thing_viewIcon'} = $session->icon->view($viewParams);
|
||||
push (@things_loop, \%templateVars);
|
||||
}
|
||||
|
|
@ -3602,6 +3787,11 @@ The unique id of a thing.
|
|||
|
||||
The unique id of a row of thing data.
|
||||
|
||||
=head3 templateId
|
||||
|
||||
Optional. The unique id or url of the template to be used. When specified, the style template is not used.
|
||||
If omitted, the thing data view template and style will be used.
|
||||
|
||||
=cut
|
||||
|
||||
sub www_viewThingData {
|
||||
|
|
@ -3610,7 +3800,7 @@ sub www_viewThingData {
|
|||
my $session = $self->session;
|
||||
my $thingId = shift || $session->form->process('thingId');
|
||||
my $thingDataId = shift || $session->form->process('thingDataId');
|
||||
|
||||
my $templateId = shift || $session->form->process('templateId');
|
||||
my $var = $self->get;
|
||||
my $url = $self->getUrl;
|
||||
my $i18n = WebGUI::International->new($self->session, "Asset_Thingy");
|
||||
|
|
@ -3640,9 +3830,19 @@ sub www_viewThingData {
|
|||
|
||||
$self->getViewThingVars($thingId,$thingDataId,$var);
|
||||
$self->appendThingsVars($var, $thingId);
|
||||
|
||||
my $template;
|
||||
if( $templateId )
|
||||
{
|
||||
$template = WebGUI::Asset::Template->newByUrl( $session, $templateId ) ||
|
||||
WebGUI::Asset::Template->newByDynamicClass( $session, $templateId );
|
||||
}
|
||||
|
||||
return $self->processStyle(
|
||||
$self->processTemplate($var,$thingProperties->{viewTemplateId})
|
||||
);
|
||||
$self->processTemplate($var,$thingProperties->{viewTemplateId})
|
||||
) if !$template;
|
||||
|
||||
return $self->processTemplate($var,$template->getId,$template);
|
||||
}
|
||||
|
||||
#-------------------------------------------------------------------
|
||||
|
|
|
|||
59
lib/WebGUI/Help/Asset_Map.pm
Normal file
59
lib/WebGUI/Help/Asset_Map.pm
Normal file
|
|
@ -0,0 +1,59 @@
|
|||
package WebGUI::Help::Asset_Map;
|
||||
use strict;
|
||||
|
||||
our $HELP = {
|
||||
|
||||
'view template' => {
|
||||
title => 'view template',
|
||||
body => '',
|
||||
isa => [
|
||||
{ namespace => 'Asset_Template',
|
||||
tag => 'template variables'
|
||||
},
|
||||
{ namespace => 'Asset_Map',
|
||||
tag => 'map asset template variables'
|
||||
},
|
||||
],
|
||||
fields => [],
|
||||
variables => [
|
||||
{ name => 'canAddPoint', },
|
||||
{ name => 'canEdit', },
|
||||
{ name => 'mapPoints', required => 1, },
|
||||
{ name => 'button_addPoint', required => 1, },
|
||||
{ name => 'button_setCenter', required => 1, },
|
||||
{ name => 'button_setCenter', selectPoint => 1, },
|
||||
],
|
||||
related => []
|
||||
},
|
||||
|
||||
'map asset template variables' => {
|
||||
private => 1,
|
||||
title => 'map asset template variables',
|
||||
body => '',
|
||||
isa => [
|
||||
{ namespace => 'Asset',
|
||||
tag => 'asset template asset variables'
|
||||
},
|
||||
],
|
||||
fields => [],
|
||||
variables => [
|
||||
{ name => 'groupIdAddPoint', },
|
||||
{ name => 'mapApiKey', },
|
||||
{ name => 'mapHeight', },
|
||||
{ name => 'mapWidth', },
|
||||
{ name => 'startLatitude', },
|
||||
{ name => 'startLongitude', },
|
||||
{ name => 'startZoom', },
|
||||
{ name => 'templateIdEditPoint', },
|
||||
{ name => 'templateIdView', },
|
||||
{ name => 'templateIdViewPoint', },
|
||||
{ name => 'workflowIdPoint', },
|
||||
{ name => 'canAddPoint', },
|
||||
{ name => 'canEdit', },
|
||||
],
|
||||
related => []
|
||||
},
|
||||
|
||||
};
|
||||
|
||||
1;
|
||||
|
|
@ -10,6 +10,9 @@ our $HELP = {
|
|||
{ namespace => 'Asset_Template',
|
||||
tag => 'template variables'
|
||||
},
|
||||
{ namespace => 'Asset_MapPoint',
|
||||
tag => 'map point asset template variables'
|
||||
},
|
||||
],
|
||||
fields => [],
|
||||
variables => [
|
||||
|
|
@ -32,6 +35,8 @@ our $HELP = {
|
|||
{ name => 'form_fax', },
|
||||
{ name => 'form_email', },
|
||||
{ name => 'user defined variables', },
|
||||
{ name => 'form_isHidden', },
|
||||
{ name => 'form_isGeocoded', },
|
||||
],
|
||||
related => []
|
||||
},
|
||||
|
|
|
|||
|
|
@ -152,6 +152,12 @@ our $HELP = {
|
|||
{ 'name' => 'field_pretext' },
|
||||
],
|
||||
},
|
||||
{
|
||||
'name' => 'variables by label',
|
||||
}
|
||||
{
|
||||
'name' => 'fields',
|
||||
}
|
||||
],
|
||||
related => [
|
||||
{ tag => 'edit thing template',
|
||||
|
|
|
|||
66
lib/WebGUI/Macro/RenderThingData.pm
Normal file
66
lib/WebGUI/Macro/RenderThingData.pm
Normal file
|
|
@ -0,0 +1,66 @@
|
|||
package WebGUI::Macro::RenderThingData;
|
||||
|
||||
#-------------------------------------------------------------------
|
||||
# WebGUI is Copyright 2001-2011 Plain Black Corporation.
|
||||
#-------------------------------------------------------------------
|
||||
# Please read the legal notices (docs/legal.txt) and the license
|
||||
# (docs/license.txt) that came with this distribution before using
|
||||
# this software.
|
||||
#-------------------------------------------------------------------
|
||||
# http://www.plainblack.com info@plainblack.com
|
||||
#-------------------------------------------------------------------
|
||||
|
||||
use strict;
|
||||
use WebGUI::Group;
|
||||
use WebGUI::Asset::Template;
|
||||
use WebGUI::Asset::Wobject::Thingy;
|
||||
|
||||
=head1 NAME
|
||||
|
||||
Package WebGUI::Macro::RenderThingData
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
Macro that allows users to render thing data.
|
||||
|
||||
=head2 process ( thingURL, templateHint )
|
||||
|
||||
=head3 thingHint
|
||||
|
||||
The URL from which to pull the thingId and thingDataId
|
||||
|
||||
=head3 templateHint
|
||||
|
||||
Optional. Specifies the templateId or template url to use. If omitted, the default thingy view template will be used.
|
||||
|
||||
=cut
|
||||
|
||||
|
||||
#-------------------------------------------------------------------
|
||||
sub process {
|
||||
my ($session, $thingDataUrl, $templateHint ) = @_;
|
||||
|
||||
my $uri = URI->new( $thingDataUrl );
|
||||
|
||||
my $urlHash = { $uri->query_form };
|
||||
my $thingId = $urlHash->{'thingId'};
|
||||
my $thingDataId = $urlHash->{'thingDataId'};
|
||||
|
||||
my $thing = WebGUI::Asset::Wobject::Thingy->newByUrl( $session, $uri->path );
|
||||
|
||||
# TODO: i18n
|
||||
return ( "Bad URL: " . $thingDataUrl ) if !$thing || !$thingId || !$thingDataId;
|
||||
|
||||
# Render
|
||||
my $output = $thing->www_viewThingData( $thingId, $thingDataId, $templateHint );
|
||||
|
||||
# FIX: Temporary solution (broken map due to template rendering <script> tags)
|
||||
return "RenderThingData: Please specify a template." if !$templateHint;
|
||||
return "RenderThingData: Contained bad tags!" if $output =~ /script>/;
|
||||
|
||||
return $output;
|
||||
}
|
||||
|
||||
|
||||
1;
|
||||
|
||||
|
|
@ -35,12 +35,12 @@ These methods are available from this package:
|
|||
|
||||
=cut
|
||||
|
||||
|
||||
#-------------------------------------------------------------------
|
||||
|
||||
=head2 addFile ( path )
|
||||
|
||||
Use an external filter defined in the config file as searchIndexerPlugins.
|
||||
Use an external filter defined in the config file as searchIndexerPlugins to pull keywords from a file and
|
||||
add them to the index.
|
||||
|
||||
=head3 path
|
||||
|
||||
|
|
@ -51,22 +51,11 @@ The path to the filename to index, including the filename.
|
|||
sub addFile {
|
||||
my $self = shift;
|
||||
my $path = shift;
|
||||
my $filters = $self->session->config->get("searchIndexerPlugins");
|
||||
my $content;
|
||||
if ($path =~ m/\.(\w+)$/) {
|
||||
my $type = lc($1);
|
||||
if ($filters->{$type}) {
|
||||
open my $fh, "$filters->{$type} $path |" or return undef; # open pipe to filter
|
||||
$content = do { local $/; <$fh> }; # slurp file
|
||||
close $fh;
|
||||
}
|
||||
}
|
||||
return $self->addKeywords($content)
|
||||
if $content =~ m/\S/; # only index if we fine non-whitespace
|
||||
return undef;
|
||||
my $keywords = $self->getKeywordsForFile($path);
|
||||
return unless $keywords =~ /\S/;
|
||||
return $self->addKeywords($keywords)
|
||||
}
|
||||
|
||||
|
||||
#-------------------------------------------------------------------
|
||||
|
||||
=head2 addKeywords ( text )
|
||||
|
|
@ -84,8 +73,39 @@ sub addKeywords {
|
|||
my $text = join(" ", @_);
|
||||
|
||||
$text = $self->_filterKeywords($text);
|
||||
my ($keywords) = $self->session->db->quickArray("select keywords from assetIndex where assetId=?",[$self->getId]);
|
||||
$self->session->db->write("update assetIndex set keywords =? where assetId=?", [$keywords.' '.$text, $self->getId]);
|
||||
my ($keywords) = $self->session->db->quickArray("select keywords from assetIndex where assetId=? and url=?",[$self->getId, $self->asset->get('url')]);
|
||||
$self->session->db->write("update assetIndex set keywords =? where assetId=? and url=?", [$keywords.' '.$text, $self->getId, $self->asset->get('url')]);
|
||||
}
|
||||
|
||||
|
||||
#-------------------------------------------------------------------
|
||||
|
||||
=head2 addRecord ( %fields )
|
||||
|
||||
Adds a duplicate record for the current asset, along with fields that are overridden.
|
||||
|
||||
=head3 %fields
|
||||
|
||||
A hash of fields to override in the record. Entries for url and keywords are mandatory, and
|
||||
no record will be added unless they exist in the hash.
|
||||
|
||||
The lineage entry cannot be overridden.
|
||||
|
||||
=cut
|
||||
|
||||
sub addRecord {
|
||||
my $self = shift;
|
||||
my %fields = @_;
|
||||
return unless $fields{url} and $fields{keywords};
|
||||
my $asset = $self->asset;
|
||||
##Get the asset's record from the database.
|
||||
my %defaults = $self->session->db->quickHash('select * from assetIndex where assetId=? and url=?', [$asset->get('assetId'), $asset->get('url')]);
|
||||
$fields{keywords} = $self->_filterKeywords($fields{keywords});
|
||||
%fields = (%defaults, %fields);
|
||||
$fields{lineage} = $defaults{lineage};
|
||||
my $add = $self->session->db->prepare("replace into assetIndex (assetId, url, title, creationDate, revisionDate,
|
||||
ownerUserId, groupIdView, groupIdEdit, lineage, className, synopsis, keywords, subId) values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ? )");
|
||||
$add->execute([@fields{qw/assetId url title creationDate revisionDate ownerUserId groupIdView groupIdEdit lineage className synopsis keywords subId/}]);
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -214,6 +234,36 @@ sub getId {
|
|||
return $self->{_id};
|
||||
}
|
||||
|
||||
#-------------------------------------------------------------------
|
||||
|
||||
=head2 getKeywordsForFile ( path )
|
||||
|
||||
Use an external filter defined in the config file as searchIndexerPlugins to get keywords
|
||||
from a file.
|
||||
|
||||
=head3 path
|
||||
|
||||
The path to the filename to index, including the filename.
|
||||
|
||||
=cut
|
||||
|
||||
sub getKeywordsForFile {
|
||||
my $self = shift;
|
||||
my $path = shift;
|
||||
my $filters = $self->session->config->get("searchIndexerPlugins");
|
||||
my $content;
|
||||
if ($path =~ m/\.(\w+)$/) {
|
||||
my $type = lc($1);
|
||||
if ($filters->{$type}) {
|
||||
open my $fh, "$filters->{$type} $path |" or return undef; # open pipe to filter
|
||||
$content = do { local $/; <$fh> }; # slurp file
|
||||
close $fh;
|
||||
}
|
||||
}
|
||||
return $content;
|
||||
}
|
||||
|
||||
|
||||
#-------------------------------------------------------------------
|
||||
|
||||
=head2 setIsPublic ( boolean )
|
||||
|
|
|
|||
|
|
@ -168,11 +168,133 @@ our $I18N = {
|
|||
lastUpdated => 0,
|
||||
context => "Choose from the list of points that existon the map",
|
||||
},
|
||||
|
||||
'assetName' => {
|
||||
message => "Map",
|
||||
lastUpdated => 0,
|
||||
context => "Name of this asset",
|
||||
},
|
||||
|
||||
'canAddPoint' => {
|
||||
message => "A boolean which is true if the current user can add a new point to the map",
|
||||
lastUpdated => 0,
|
||||
context => "template variable help",
|
||||
},
|
||||
|
||||
'canEdit' => {
|
||||
message => "A boolean which is true if the current user can edit this Map asset",
|
||||
lastUpdated => 0,
|
||||
context => "template variable help",
|
||||
},
|
||||
|
||||
'map asset template variables' => {
|
||||
message => "Map Asset Template Variables",
|
||||
lastUpdated => 0,
|
||||
context => "template variable help",
|
||||
},
|
||||
|
||||
'view template' => {
|
||||
message => "Map Asset View Template",
|
||||
lastUpdated => 0,
|
||||
context => "template variable help",
|
||||
},
|
||||
|
||||
'groupIdAddPoint' => {
|
||||
message => "The GUID of the group that can add points to the Map",
|
||||
lastUpdated => 0,
|
||||
context => "template variable help",
|
||||
},
|
||||
|
||||
'mapApiKey' => {
|
||||
message => "The Google Maps API key",
|
||||
lastUpdated => 0,
|
||||
context => "template variable help",
|
||||
},
|
||||
|
||||
'mapHeight' => {
|
||||
message => "The height of the map, in pixels",
|
||||
lastUpdated => 0,
|
||||
context => "template variable help",
|
||||
},
|
||||
|
||||
'mapWidth' => {
|
||||
message => "The width of the map, in pixels",
|
||||
lastUpdated => 0,
|
||||
context => "template variable help",
|
||||
},
|
||||
|
||||
'startLatitude' => {
|
||||
message => "The starting latitude of the map, for the center",
|
||||
lastUpdated => 0,
|
||||
context => "template variable help",
|
||||
},
|
||||
|
||||
'startLongitude' => {
|
||||
message => "The starting longitude of the map, for the center",
|
||||
lastUpdated => 0,
|
||||
context => "template variable help",
|
||||
},
|
||||
|
||||
'startZoom' => {
|
||||
message => "The starting zoom level of the map",
|
||||
lastUpdated => 0,
|
||||
context => "template variable help",
|
||||
},
|
||||
|
||||
'templateIdEditPoint' => {
|
||||
message => "The GUID of the template for addding or editing a point.",
|
||||
lastUpdated => 0,
|
||||
context => "template variable help",
|
||||
},
|
||||
|
||||
'templateIdView' => {
|
||||
message => "The GUID of the template for viewing the map.",
|
||||
lastUpdated => 0,
|
||||
context => "template variable help",
|
||||
},
|
||||
|
||||
'templateIdViewPoint' => {
|
||||
message => "The GUID of the template for viewing a point of the map.",
|
||||
lastUpdated => 0,
|
||||
context => "template variable help",
|
||||
},
|
||||
|
||||
'workflowIdPoint' => {
|
||||
message => "The GUID of the workflow for committing a Map Point.",
|
||||
lastUpdated => 0,
|
||||
context => "template variable help",
|
||||
},
|
||||
|
||||
'mapPoints' => {
|
||||
message => "A loop of map points. See the MapPoint template variables for a list of available ones.",
|
||||
lastUpdated => 0,
|
||||
context => "template variable help",
|
||||
},
|
||||
|
||||
'mapPoints' => {
|
||||
message => "A loop of map points. See the MapPoint template variables for a list of available ones.",
|
||||
lastUpdated => 0,
|
||||
context => "template variable help",
|
||||
},
|
||||
|
||||
'button_addPoint' => {
|
||||
message => "A templated button with internationalized label to add a button.",
|
||||
lastUpdated => 0,
|
||||
context => "template variable help",
|
||||
},
|
||||
|
||||
'button_setCenter' => {
|
||||
message => "A templated button with internationalized label to set the center of the map back to the default.",
|
||||
lastUpdated => 0,
|
||||
context => "template variable help",
|
||||
},
|
||||
|
||||
'selectPoint' => {
|
||||
message => "A templated dropdown to center the map on a point, and to display it's information.",
|
||||
lastUpdated => 0,
|
||||
context => "template variable help",
|
||||
},
|
||||
|
||||
};
|
||||
|
||||
1;
|
||||
|
|
|
|||
|
|
@ -133,7 +133,16 @@ our $I18N = {
|
|||
lastUpdated => 0,
|
||||
context => 'Description of asset property',
|
||||
},
|
||||
|
||||
'isGeocoded label' => {
|
||||
message => 'Automatically Position',
|
||||
lastUpdated => 0,
|
||||
context => 'Label for asset property',
|
||||
},
|
||||
'isGeocoded description' => {
|
||||
message => q{Choose whether or not this map point should be automatically positioned having it's latitude and longitude dynamically set based on the address. Choosing "Yes" will make the point unable to be moved on the map.},
|
||||
lastUpdated => 0,
|
||||
context => 'Description of asset property',
|
||||
},
|
||||
'assetName' => {
|
||||
message => "MapPoint",
|
||||
lastUpdated => 0,
|
||||
|
|
@ -380,6 +389,17 @@ our $I18N = {
|
|||
context => "template variable help",
|
||||
},
|
||||
|
||||
'form_isHidden' => {
|
||||
message => "A yes/no field indicating whether or not the Map Point should display in navigations.",
|
||||
lastUpdated => 0,
|
||||
context => "template variable help",
|
||||
},
|
||||
|
||||
'form_isGeocoded' => {
|
||||
message => "A checkbox field indicating whether or not the Map Point should be automatically placed on the map based on it's address.",
|
||||
lastUpdated => 0,
|
||||
context => "template variable help",
|
||||
},
|
||||
};
|
||||
|
||||
1;
|
||||
|
|
|
|||
|
|
@ -1144,6 +1144,12 @@ below/after the form element.|,
|
|||
context => q|Status message in the Export Thingy progress bar. %s is the name of the Thing that is being exported.|,
|
||||
},
|
||||
|
||||
'variables by label' => {
|
||||
message => q|In addition to the <b>field_loop</b>, field values may be directly accessed via their label. Please check the documentation for the template plugin that you are using to handle odd characters like spaces or quotes in the label.|,
|
||||
lastUpdated => 1231180362,
|
||||
context => q|Template variable help for getViewThingData|,
|
||||
},
|
||||
|
||||
};
|
||||
|
||||
1;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue