Op deze pagina vind je een bron van : 

  • CxScript
  • snippets
  • howto's
  • hownotto's
  • gotcha's
  • anekdotes
  • ect.

Voorgedefinieerde variabelen

De volgende variabelen zijn standaard alle sjablonen beschikbaar:

De volgende variabelen zijn standaard beschikbaar in documentsjablonen:

Enkele globale objecten zijn alleen via een omweg te bereiken:

Voorbeelden

Naam van de klant: <cx:write value="$utilities.userDefaults.Customer"/>
Gebruikte browser: <cx:write value="$request.headers" invoke="user-agent.@first"/>

Listige fetches

Kandidaten zonder ingevuld e-mailadres:

<cx:let name="q" value="emailAddress != nil" invoke="qualifierValue">
<cx:fetch entity="CREmployee" qualifier="not (toUser.emailAddresses matchesQualifier: $q)">
<cx:write value="$item.informalName"/><br />
</cx:fetch>
</cx:let>

Gotcha: relaties in qualifiers

Probleem: we zoeken kandidaten met skill X EN skill Y maar het volgende levert geen resultaat:

<cx:fetch entity="CREmployee" qualifier="(skills.toSkillLevel2.value = X AND skills.toSkillLevel2.value = Y)">

Oorzaak: per relatie wordt precies een join gegenereerd, hoe vaak deze ook wordt genoemd in de qualifier. Key-paden met een bepaalde to-many relatie erin (zoals "skills") hebben daarom betrekking op steeds hetzelfde object uit die relatie. Hierboven wordt dus in feite gezocht naar één waarde die zowel X als Y is!

Deze "koppeling" kan op twee manieren worden omzeild. De eerste manier is het gebruik van een tweede relatie met dezelfde definitie, en als naam de oorspronkelijke naam met een nummer erachter (bijv. "skills2"). De qualifier wordt dan

(skills.toSkillLevel2.value = X AND skills2.toSkillLevel2.value = Y)

De tweede, algemeen bruikbare manier is het gebruik van subqueries. Dat kan door middel van de volgende constructie:

<cx:let name="q1" value="toSkillLevel2.value = X" invoke="qualifierValue">
<cx:let name="q2" value="toSkillLevel2.value = Y" invoke="qualifierValue">
<cx:fetch entity="CREmployee" qualifier="(skills matchesQualifier: $q1) AND (skills matchesQualifier: $q2)">
...
</cx:fetch>
</cx:let></cx:let>

Directe SQL qualifiers

Deze zijn database-specifiek (in ons geval dus: PostgreSQL 8.2 of later). Alleen gebruiken wanneer berekeningen of bewerkingen op de kolomwaarden nodig zijn.

Voorbeeld: kandidaten die vandaag jarig zijn. Hierbij moet het jaartal van de geboortedatum en de huidige datum buiten beschouwing blijven.

<cx:fetch entity="CREmployee" sqlqualifier="to_char(toUser.birthDate, 'DD-MM') = to_char(current_date, 'DD-MM')">
<cx:write value="$item.informalName"/><br />
</cx:fetch>

Voorbeeld: Vacatures waarvan de standplaats binnen een straal van $d km van postcode $pc ligt. Hierbij wordt met de coordinaten van elke vacature een afstandsbereking gedaan.

<cx:let name="clu" value="CXCoordLookup" invoke="namedClass.sharedInstance.coordinates">
<cx:let name="pc4" value="$pc" invoke="substringWithMaxLength:" arg0="4">
<cx:let name="co" condition="$pc4.length > 0" iftrue="$clu" invoke="$pc4">
<cx:let name="dm" value="$d.numberValue" invoke="numberByMultiplyingBy:" arg0="1000">
<cx:let name="sql" condition="($co != nil) and ($dm > 0)" iftrue="
toVacancy.coordX >= ${co.x} - ${dm} AND toVacancy.coordX <= ${co.x} + ${dm} AND
toVacancy.coordY >= ${co.y} - ${dm} AND toVacancy.coordY <= ${co.y} + ${dm} AND
(toVacancy.coordX - ${co.x})^2 + (toVacancy.coordY - ${co.y})^2 <= ${dm}^2" expand="1">
<cx:fetch entity="CRVacancy" sqlqualifier="$sql">
...
</cx:fetch>
</cx:let></cx:let></cx:let></cx:let></cx:let>

Lijsten en datanodes

In het algemeen is het beter om CRDataNode objecten niet te fetchen, maar op te halen uit de CRDataNodeCache. Bijvoorbeeld:

<cx:let name="dnc" value="CRDataNodeCache" invoke="namedClass.cache">
<cx:foreach list="$dnc.Product">
<cx:write value="$item.value"/>
</cx:foreach>
</cx:let>

Bewerkingen op strings

Concateneren (aan elkaar plakken) van stringvariabelen en letterlijke tekst:

<cx:let name="result" value="Kandidaat: ${emp.informalName} (${emp.age} jaar)" expand="1">
...
</cx:let>

De eerste 100 tekens van $s:

<cx:write value="$s" invoke="substringWithMaxLength:" arg0="100"/>

Vervangen van alle euro-tekens in $s door de tekst "euro":

<cx:write value="$s" invoke="replace:by:" arg0="€" arg1="euro"/>

Gotcha: lege attribuutwaarde

In dit voorbeeld wordt gepoogd een substring te verwijderen:

<cx:write value="$activity.toEmployee.formalClosing" invoke="replace:by:" arg0="De heer " arg1=""/>

Dit geeft echter een onverwacht resultaat: "De heer Jansen" wordt "arg1 Jansen"!

De oorzaak is een "feature" (van WebObjects) die bij lege attribuutwaarden de naam van het attribuut invult. Dus foobar="" wordt foobar="foobar" in de HTML.

Hiervoor is een simpele workaround: arg1="$nil" (of een willekeurige ongedefinieerde variabele).

Rekenen

Gemiddelde van $x en $y:

<cx:let name="sum" value="$x" invoke="numberByAdding:" arg0="$y">
<cx:let name="avg" value="$sum" invoke="numberByDividingBy:" arg0="2">
<cx:write value="$avg"/>
</cx:let>
</cx:let>

Overig

conditionele let:

<cx:let name="prod" condition="form.pub.count > 0" ifTrue="$p.toVacancy.productTypeNode" ifFalse="$form.prod.@first.numberValue">
...
</cx:let>

Meta tag voor content-type:

<cx:let name="sc" value="NSString" invoke="namedClass.self">
<cx:let name="cs" value="$sc" invoke="charsetNameForStringEncoding:" arg0="$_.context.response.contentEncoding">
<meta http-equiv="content-type" content="text/html; charset=<cx:write value='$cs'/>">
</cx:let></cx:let>

Link naar (recentste) CV van kandidaat $emp (in HTML documentsjabloon):

<cx:foreach item="cv" list="$emp.attachments.@sortDescending.creationDate" filter="toTypeNode hasTag: 'CVTag'" count="1">
<cx:if condition="$cv.content.length > 0">
<cx:hyperlink target="_blank" type="$cv.filePath.mimeTypeFromPath" data="$cv.content">Bekijk CV</cx:hyperlink>
</cx:if>
</cx:foreach>

Underdrukken whitespace:

<cx:bare-string-format>
"foo bar
baz<cx:write value=" "/>quux"
</cx:bare-string-format>

geeft:

"foobarbaz quux"

Alleen de laatste spatie is dus behouden gebleven, omdat deze expliciet binnen een CxWrite stond. ("\n" werkt als verwacht) 

Heeft u het antwoord gevonden?