HTL AEM conditional OR operator issue - aem

I want to be able to use the "||" OR operator in this context
inside a schema, i have two dates I need to pull from the JCR content if the value in the field has not been the author
<script type="application/ld+json" >
"datePublished": "${properties.datePublishedArticle #context="html" ||'yyyy-MM-dd' # format=currentPage.lastModified }",
"dateModified": "${properties.dateModifiedArticle # context="html" || 'yyyy-MM-dd' # format=currentPage.lastModified}"
</script>
org.apache.sling.api.scripting.ScriptEvaluationException:
mismatched input '#' expecting {'}', '.', 'in', '&&', '||', ',', '['} in line 67 where datepublished is located.
In order words, if author has not authored a value, it will take the value from the jcr content. They work fine when done separately.
Do not understand the error that is indicating.

Have you tried to use it like this:
<script type="application/ld+json" >
"datePublished": "${properties.datePublishedArticle ||'yyyy-MM-dd' # context="html", format = currentPage.lastModified }",
"dateModified": "${properties.dateModifiedArticle || 'yyyy-MM-dd' # context="html", format = currentPage.lastModified}"
</script>
I would think that the error is happening because you shouldn't be repeating the '#' block in the same HTL statement.

Although #atgar's solution does not throw an error, I think it does not do what the author asked for: output either the authored date or the JCR (lastModified) date.
Something like this would be closer to what he needs:
<script type="application/ld+json" >
"datePublished": "${'yyyy-MM-dd' # context='html', format = (properties.datePublishedArticle ? properties.datePublishedArticle : currentPage.lastModified) }",
"dateModified": "${'yyyy-MM-dd' # context='html', format = (properties.dateModifiedArticle ? properties.dateModifiedArticle : currentPage.lastModified)}"
</script>
Please note, when using HTL date formatting, the actual values should be in the format option.

Related

Use Arrays and for-loops in BICEP

I am passing an array of services into the BICEP template
param objectarray array =[]
I also have an array variable that contains a subset of the service names that I passed in
var objectarray =
[
'Abc'
'DEF'
'GHI'
]
My intention is to see if the service names being passed in are in the subset and if so, then I need to set another variable accordingly. What's the best way to do that? I've used conditional loops and if statements in BICEP before but not together.
var isInSubset =
Additional Info
I did try this
var apis_with_listener = contains(objectarray, objectarray)
but the resource that I am creating is a backend policy and i am using a for loop in the resource creation and setting the value based on what apis_with_listener is set to. Sorry, this sounds confusing.
value: '<\r\n<policies>\r\n <inbound>\r\n <base />\r\n <set-backend-service backend-id="${APIM_Name}" sf-resolve-condition="#(context.LastError?.Reason == "BackendConnectionFailure")" sf-service-instance-name="#("fabric:/${Application_Name}${Customer_AreaName}/${api}")" **sf-listener-name="${api}Service**" />\r\n </inbound>\r\n <backend>\r\n <base />\r\n </backend>\r\n <outbound>\r\n <base />\r\n </outbound>\r\n <on-error>\r\n <base />\r\n </on-error>\r\n</policies>'
so the sf-listener-name needs to be set ONLY if the service is one of the ones in the subset. Not sure how to do a for loop and an if properly
resource BackendPolicy 'Microsoft.ApiManagement/service/apis/policies#2021-04-01-preview'= [for (api,i) in API_Names : {
name: 'policy'
parent:API_Service[i]
properties: {
value: '<\r\n<policies>\r\n <inbound>\r\n <base />\r\n <set-backend-service backend-id="${APIM_Name}" sf-resolve-condition="#(context.LastError?.Reason == "BackendConnectionFailure")" sf-service-instance-name="#("fabric:/${Application_Name}${Customer_AreaName}/${api}")" sf-listener-name="${api}Service" />\r\n </inbound>\r\n <backend>\r\n <base />\r\n </backend>\r\n <outbound>\r\n <base />\r\n </outbound>\r\n <on-error>\r\n <base />\r\n </on-error>\r\n</policies>'
format: 'xml'
}
}]
First of all, Bicep doesn't allow loops within loops, but you don't need that here as you're just looking for whether an array contains the string value you're matching against. Let's start my saying that all the APIM policy setting is going to happen in its own module, 'sf-apimPolicy.bicep', for clarity.
You indicated that you want to pass in an array of your Service Fabric service names and see if any of them are in a subset, presumably one kept in your intended module, so we'll start with that.
// sf-apimPolicy.bicep
#description('Your APIM resource name')
param APIM_Name string
#description('The prefix of your SF application name')
param Application_Name string
#description('Used to route to the appropriate SF application per customer')
param Customer_AreaName string
#description('Contains each of your Service names being passed in')
param API_Names array //Presumably this is the 'objectarray' you mention in the question
#description('The array of service names that set a constraint on what can be set in this policy')
param ApiNameConstraints array
resource ApimService 'Microsoft.ApiManagement/service/apis#2021-04-01-preview' existing = {
name: '${APIM_Name}/${ApiServiceName}'
}
//And finally you're looking to set the policy itself if ApiNameConstraints contains your api value
resource BackendPolicy 'Microsoft.ApiManagement/service/apis/policies#2021-04-01-preview' = [for (api, i) in API_Names: if (contains(ApiNameConstraints, api)): {
name: 'policy'
parent: ApimService
properties: {
value: '''
<policies>
<inbound>
<base> // As an aside, changed this from your original value as it used a content-less close tag
<set-backend-service backend-id="${APIM_Name}" sf-resolve-condition="#(context.LastError?.Reason == "BackendConnectionFailure")" sf-service-instance-name="#("fabric:/${Application_Name}${Customer_AreaName}/${api}")" **sf-listener-name="${api}Service**" />
</base> //Also changed this as it didn't use a close tag
</inbound>
<backend>
<base />
</backend>
<outbound>
<base />
</outbound>
<on-error>
<base />
</on-error>
</policies>
'''
format: 'xml'
}
}]
Then merely call this module and populate the various parameters to call it and the loop will be handled internally.

Mongodb '$where' query using javascript regex

I am trying to reproduce the REPLACE function in sql on mongodb.
My collection 'log' has this data in the 'text' field.
[01]ABC0007[0d0a]BB BABLOXC[0d0a]067989 PLPXBNS[0d0a02]BBR OIC002 L5U0/P AMD KAP 041800 T1200AND 2+00[0d0a0b03]
All I'm trying to do is remove the '[..]' using regex (javascript) and use contains('PLPXBNSBBR') like this so that the expression return true per the javadocs in mongo documentation.
This query below successfully works and returns the matching rows.
db.log.find({"$where":"return this.message.replace(new RegExp('0d0a02'),'').contains('PLPXBNS[]BBR') "});
However, I would need to remove the '[..]' and match like this PLPXBNSBBR.
These are the ones I tried unsuccessfully
db.log.find({"$where" : " return this.message.replace( new
RegExp('\[.*?\]', 'g'), '' ).contains('PLPXBNSBBR') " });
db.log.find({"$where" : " return this.message.replace( new
RegExp('/[(.*?)]', 'g'), '' ).contains('PLPXBNSBBR') " });
db.log.find({"$where" : " return this.message.replace( new
RegExp('//[.*//]'), '' ).contains('PLPXBNSBBR') " });
db.log.find({"$where" : " return this.message.replace( new
RegExp('[.*?]'), '' ).contains('PLPXBNSBBR') " });
From the earlier discussion it appears that if I can pass the pattern as /[[^]]+]/g, it should strip the [..] but it is not doing that and not returning the matching rows.
Okay, I was able to use chaining replace successfully to get my desired results.

Selecting a field in Protractor

<hs-details-item>
<hs-label>Location</hs-label>
<hs-value-block>
<hs>
<hs-text-box ng-class="{'disabled': isAmenityPosting }" class="required" input-control="{title:'Location', okCallback:setJobSite, value:jobSiteName,
autocomplete:{ values:getJobSiteList, reload: true }, ss:'location'}">
<i class="icon-room"></i><span hs-placeholder="Select Location" class="ng-binding"></span>
</hs-text-box>
</hs>
<hs>
<!-- ngIf: isBarcodeShow() --><hs-button ng-class="{'disabled': soCreating }" class="barcode-special-btn smaller ng-scope" ng-if="isBarcodeShow()" hs-gesture="{handler:startScan, param: onBarcodeScanCompleted}"><i class="icon-br-code"></i></hs-button><!-- end ngIf: isBarcodeShow() -->
</hs>
</hs-value-block>
</hs-details-item>
Scenario: click on “Location” field...
What would be the best way to come up with a command in Protractor to select "location" field from the above Snippet Code?
Can it be done by not using Xpath?
Multiple options here. A sort of a non-welcomed, but short and readable way, would be to use an XPath expression and check the preceding label:
var locationTextBox = element(by.xpath("//hs-label[. = 'Location']/following::hs-text-box"));
locationTextBox.click();

Errors in codeigniter-restserver library

I want to use restful in my ci 3.03 application:
I found this tutplus tutorial
I downloaded codeigniter-restserver-master.zip file and copied Format.php and REST_Controller.php(#version 3.0.0) files into /application/libraries/REST directory
I created control application/controllers/api/Users.php :
require_once("application/libraries/REST/REST_Controller.php");
require_once("application/libraries/REST/Format.php");
class Users extends REST_Controller
{
//protected $rest_format = 'json';
function users_get()
{
//$users = $this->user_model->get_all();
$filter_username= $this->get('filter_username');
$filter_user_group= $this->get('filter_user_group');
$filter_active= $this->get('filter_active');
$sort= $this->get('sort');
$sort_direction= $this->get('sort_direction');
//, $filter_user_group, $filter_active, $sort, $sort_direction
$users_list = $this->muser->getUsersList(false, ''/*, $filter_username, $filter_user_group, $filter_active, $sort, $sort_direction, ''*/);
echo '<pre>'.count($users_list).'::$users_lists::'.print_r($users_list,true).'</pre>';
if($users_list)
{
$this->response($users, 200);
}
else
{
$this->response(NULL, 404);
}
}
AND RUNNING URL http://local-ci3.com/api/users I got many errors:
A PHP Error was encountered
Severity: Notice
Message: Undefined property: Users::$format
Filename: REST/REST_Controller.php
Line Number: 734
Backtrace:
File: /mnt/diskD_Work/wwwroot/ci3/application/libraries/REST/REST_Controller.php
Line: 734
Function: _error_handler
File: /mnt/diskD_Work/wwwroot/ci3/application/libraries/REST/REST_Controller.php
Line: 649
Function: response
File: /mnt/diskD_Work/wwwroot/ci3/index.php
Line: 292
Function: require_once
A PHP Error was encountered
Severity: Notice
Message: Undefined property: Users::$format
Filename: REST/REST_Controller.php
Line Number: 752
Backtrace:
File: /mnt/diskD_Work/wwwroot/ci3/application/libraries/REST/REST_Controller.php
Line: 752
Function: _error_handler
File: /mnt/diskD_Work/wwwroot/ci3/application/libraries/REST/REST_Controller.php
Line: 649
Function: response
File: /mnt/diskD_Work/wwwroot/ci3/index.php
Line: 292
Function: require_once
Actually I wanted to get some workable library to help me with REST api creation. I think that is preferable way istead of making from zero.
But is this library not workable or does it needs for some fixing? Sorry, what I missed is if this library only for ci 2?
I made search on this forum and found such hint :
I have the same problem when I load both Format.php and
Rest_Controller.php into a controller. After have a quick glance at
Format.php, it appears to be a standalone format conversion helper.
Try to just load Rest_Controller.php and see if your problem goes
away.
I commented line
//require_once("application/libraries/REST/Format.php");
in my controller, but I still get errors like :
Message: Undefined property: Users::$format.
I tried to review code of this library and see that invalid block when data are converted to json format, line 731-757 :
elseif ($data !== NULL)
{
// If the format method exists, call and return the output in that format
if (method_exists($this->format, 'to_' . $this->response->format))
{
// Set the format header
$this->output->set_content_type($this->_supported_formats[$this->response->format], strtolower($this->config->item('charset')));
$output = $this->format->factory($data)->{'to_' . $this->response->format}();
// An array must be parsed as a string, so as not to cause an array to string error
// Json is the most appropriate form for such a datatype
if ($this->response->format === 'array')
{
$output = $this->format->factory($output)->{'to_json'}();
}
}
else
{
// If an array or object, then parse as a json, so as to be a 'string'
if (is_array($data) || is_object($data))
{
$data = $this->format->factory($data)->{'to_json'}();
}
// Format is not supported, so output the raw data as a string
$output = $data;
}
}
If I tried to commented this block, but get error
Message: Array to string conversion
Looks like data are not converted in this case...
Is is possible to fix these errors?
Or can you, please, to tell me advice some codeigniter 3 REST api workable library with similar interface like library above?
Thanks!
I use that lib, work just fine. My suggestion is follow the more relevant installation instruction on github .
you also wrong place the lib file :
Tutorial say :
require(APPPATH'.libraries/REST_Controller.php');
You try :
require_once("application/libraries/REST/REST_Controller.php");
require_once("application/libraries/REST/Format.php");
No need to include the format because on line 407 the lib will load it. And also good to know on line 404 it will load the configuration (application/config/rest.php) it will be your default configuration, and also you can change it to suit your need.
Please let me know if you still got error using my answer :)

Pulling Data from Google spreadsheet

I am having difficulty pulling data from Google spreadsheet
I have added following gem files
gem 'roo'
gem 'google_drive'
gem 'google-spreadsheet-ruby'
My jobs file is
require 'roo'
require 'rubygems'
def fetch_spreadsheet_data()
google_user = "MY EMAIL ADDRESS"
google_password = "MY PASSWORD"
workbook = Roo::Google.new("https://docs.google.com/spreadsheet/ccc?key=1hdwnrDsuJId1FLE0yWICYP1HGqYNu2NHH2IcoPyAzOQ#gid=0",user: google_user, password: google_password)
send_event('catchup_data', {current: s.cell('B',2) })
send_event('Bounced_back', {current: s.cell('B',3) )
end
SCHEDULER.every '5m' do
fetch_spreadsheet_data()
end
My dashboard.erb file has following html
<li data-row="2" data-col="3" data-sizex="1" data-sizey="1">
<div data-id="bounce_back" data-view="Number" data-title="Triage - Work in Progress" style="background-color:#5AC352;"></div>
</li>
<li data-row="2" data-col="4" data-sizex="1" data-sizey="1">
<div data-id="catchup_data" data-view="Number" data-title="Squad catchup sessions last month" style="background-color:#DBA901;"></div>
</li>
Not sure what am I missing that the data is not coming through. Can anyone please help me?
There are a few things wrong that I can see:
You're sending 'Bounced_back' but binding to the id of 'bounce_back'
You are trying to get the cell data from 's' but 's' is undefined
Looking at the Roo docs, I believe you have copied 's' from there. Just above that, they use sheet instead so I believe you have to grab the sheet from the workbook before using it.
I googled a bit and found this: http://etzelstorfer.com/en/dashing-graph-from-google-spreadsheet/
In summary, this should work for you:
def fetch_spreadsheet_data()
google_user = "MY EMAIL ADDRESS"
google_password = "MY PASSWORD"
workbook = Roo::Google.new("https://docs.google.com/spreadsheet/ccc?key=1hdwnrDsuJId1FLE0yWICYP1HGqYNu2NHH2IcoPyAzOQ#gid=0",user: google_user, password: google_password)
s = workbook.sheets[0] # assuming first sheet in workbook
send_event('catchup_data', {current: s.cell('B',2) })
send_event('bounce_back', {current: s.cell('B',3) )
end
SCHEDULER.every '5m' do
fetch_spreadsheet_data()
end