Code Coverage |
||||||||||
Lines |
Functions and Methods |
Classes and Traits |
||||||||
| Total | |
0.00% |
0 / 199 |
|
0.00% |
0 / 35 |
CRAP | |
0.00% |
0 / 1 |
| PFTemplateField | |
0.00% |
0 / 199 |
|
0.00% |
0 / 35 |
11130 | |
0.00% |
0 / 1 |
| create | |
0.00% |
0 / 12 |
|
0.00% |
0 / 1 |
30 | |||
| toWikitext | |
0.00% |
0 / 26 |
|
0.00% |
0 / 1 |
210 | |||
| newFromParams | |
0.00% |
0 / 26 |
|
0.00% |
0 / 1 |
210 | |||
| setTypeAndPossibleValues | |
0.00% |
0 / 25 |
|
0.00% |
0 / 1 |
72 | |||
| setSemanticProperty | |
0.00% |
0 / 3 |
|
0.00% |
0 / 1 |
2 | |||
| setCargoFieldData | |
0.00% |
0 / 21 |
|
0.00% |
0 / 1 |
72 | |||
| getFieldName | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
| getValueLabels | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
| getLabel | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
| getSemanticProperty | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
| getPropertyType | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
| getExpectedCargoField | |
0.00% |
0 / 3 |
|
0.00% |
0 / 1 |
6 | |||
| getFullCargoField | |
0.00% |
0 / 3 |
|
0.00% |
0 / 1 |
12 | |||
| getFieldType | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
| getRealFieldType | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
| getPossibleValues | |
0.00% |
0 / 3 |
|
0.00% |
0 / 1 |
6 | |||
| getHierarchyStructure | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
| isList | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
| getDelimiter | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
| getDisplay | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
| getNSText | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
| getNamespace | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
| getCategory | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
| getForm | |
0.00% |
0 / 13 |
|
0.00% |
0 / 1 |
30 | |||
| isMandatory | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
| isUnique | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
| getRegex | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
| getHoldsTemplate | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
| setLabel | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
| setNamespace | |
0.00% |
0 / 2 |
|
0.00% |
0 / 1 |
2 | |||
| setNSText | |
0.00% |
0 / 3 |
|
0.00% |
0 / 1 |
2 | |||
| setFieldType | |
0.00% |
0 / 4 |
|
0.00% |
0 / 1 |
6 | |||
| setPossibleValues | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
| setHierarchyStructure | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
| createText | |
0.00% |
0 / 34 |
|
0.00% |
0 / 1 |
342 | |||
| 1 | <?php |
| 2 | |
| 3 | use MediaWiki\Title\Title; |
| 4 | |
| 5 | /** |
| 6 | * Defines a class, PFTemplateField, that represents a field in a template, |
| 7 | * including any possible Cargo or SMW storage it may have. Used in both |
| 8 | * creating templates and displaying user-created forms. |
| 9 | * |
| 10 | * @author Yaron Koren |
| 11 | * @file |
| 12 | * @ingroup PF |
| 13 | */ |
| 14 | |
| 15 | class PFTemplateField { |
| 16 | private $mFieldName; |
| 17 | private $mValueLabels; |
| 18 | private $mLabel; |
| 19 | |
| 20 | /** |
| 21 | * SMW-specific fields |
| 22 | */ |
| 23 | private $mSemanticProperty; |
| 24 | private $mPropertyType; |
| 25 | |
| 26 | /** |
| 27 | * Cargo-specific fields |
| 28 | */ |
| 29 | private $mCargoTable; |
| 30 | private $mCargoField; |
| 31 | private $mFieldType; |
| 32 | private $mRealFieldType = null; |
| 33 | private $mHierarchyStructure; |
| 34 | |
| 35 | private $mPossibleValues; |
| 36 | private $mIsList; |
| 37 | private $mDelimiter; |
| 38 | private $mDisplay; |
| 39 | private $mNSText = null; |
| 40 | private $mNamespace = 0; |
| 41 | private $mCategory = null; |
| 42 | private $mForm = null; |
| 43 | private $mIsMandatory = false; |
| 44 | private $mIsUnique = false; |
| 45 | private $mRegex = null; |
| 46 | private $mHoldsTemplate = null; |
| 47 | |
| 48 | static function create( $name, $label, $semanticProperty = null, $isList = null, $delimiter = null, $display = null ) { |
| 49 | $f = new PFTemplateField(); |
| 50 | $f->mFieldName = trim( str_replace( '\\', '', $name ) ); |
| 51 | if ( $label !== null ) { |
| 52 | // Keep this field null if no value was set. |
| 53 | $f->mLabel = trim( str_replace( '\\', '', $label ) ); |
| 54 | } |
| 55 | if ( $semanticProperty !== null ) { |
| 56 | $f->setSemanticProperty( $semanticProperty ); |
| 57 | } |
| 58 | $f->mIsList = $isList; |
| 59 | $f->mDelimiter = $delimiter; |
| 60 | $f->mDisplay = $display; |
| 61 | // Delimiter should default to ','. |
| 62 | if ( $isList && !$delimiter ) { |
| 63 | $f->mDelimiter = ','; |
| 64 | } |
| 65 | return $f; |
| 66 | } |
| 67 | |
| 68 | public function toWikitext() { |
| 69 | $attribsStrings = []; |
| 70 | // Only include the label if it's different from the field name. |
| 71 | if ( $this->mLabel != '' && |
| 72 | ( $this->mLabel !== $this->mFieldName ) ) { |
| 73 | $attribsStrings['label'] = $this->mLabel; |
| 74 | } |
| 75 | if ( $this->mCargoField != '' && $this->mCargoField !== str_replace( ' ', '_', $this->mFieldName ) ) { |
| 76 | $attribsStrings['cargo field'] = $this->mCargoField; |
| 77 | } |
| 78 | // Only set list and delimiter information if there's no Cargo |
| 79 | // field - if there is, they will be set in #cargo_declare. |
| 80 | if ( $this->mCargoField == '' ) { |
| 81 | if ( $this->mIsList == true ) { |
| 82 | $attribsStrings['list'] = true; |
| 83 | if ( $this->mDelimiter != ',' ) { |
| 84 | $attribsStrings['delimiter'] = $this->mDelimiter; |
| 85 | } |
| 86 | } |
| 87 | } |
| 88 | if ( $this->mSemanticProperty != '' ) { |
| 89 | $attribsStrings['property'] = $this->mSemanticProperty; |
| 90 | } |
| 91 | if ( $this->mNSText != null ) { |
| 92 | $attribsStrings['namespace'] = $this->mNSText; |
| 93 | } |
| 94 | if ( $this->mDisplay != '' ) { |
| 95 | $attribsStrings['display'] = $this->mDisplay; |
| 96 | } |
| 97 | $text = $this->mFieldName; |
| 98 | if ( count( $attribsStrings ) > 0 ) { |
| 99 | $attribsFullStrings = []; |
| 100 | foreach ( $attribsStrings as $key => $value ) { |
| 101 | if ( $value === true ) { |
| 102 | $attribsFullStrings[] = $key; |
| 103 | } else { |
| 104 | $attribsFullStrings[] = "$key=$value"; |
| 105 | } |
| 106 | } |
| 107 | $text .= ' (' . implode( ';', $attribsFullStrings ) . ')'; |
| 108 | } |
| 109 | return $text; |
| 110 | } |
| 111 | |
| 112 | static function newFromParams( $fieldName, $fieldParams ) { |
| 113 | $f = new PFTemplateField(); |
| 114 | $f->mFieldName = $fieldName; |
| 115 | foreach ( $fieldParams as $key => $value ) { |
| 116 | if ( $key == 'label' ) { |
| 117 | $f->mLabel = $value; |
| 118 | } elseif ( $key == 'cargo field' ) { |
| 119 | $f->mCargoField = $value; |
| 120 | } elseif ( $key == 'property' ) { |
| 121 | $f->setSemanticProperty( $value ); |
| 122 | } elseif ( $key == 'list' ) { |
| 123 | $f->mIsList = true; |
| 124 | } elseif ( $key == 'delimiter' ) { |
| 125 | $f->mDelimiter = $value; |
| 126 | } elseif ( $key == 'namespace' ) { |
| 127 | $f->setNSText( $value ); |
| 128 | } elseif ( $key == 'display' ) { |
| 129 | $f->mDisplay = $value; |
| 130 | } elseif ( $key == 'holds template' ) { |
| 131 | $f->mHoldsTemplate = $value; |
| 132 | } elseif ( $key == 'category' ) { |
| 133 | $f->mCategory = $value; |
| 134 | } elseif ( $key == 'form' ) { |
| 135 | $f->mForm = $value; |
| 136 | } |
| 137 | } |
| 138 | // Delimiter should default to ','. |
| 139 | if ( $f->mIsList && !$f->mDelimiter ) { |
| 140 | $f->mDelimiter = ','; |
| 141 | } |
| 142 | return $f; |
| 143 | } |
| 144 | |
| 145 | function setTypeAndPossibleValues() { |
| 146 | if ( !defined( 'SMW_NS_PROPERTY' ) ) { |
| 147 | return; |
| 148 | } |
| 149 | |
| 150 | // The presence of "-" at the beginning of a property name |
| 151 | // (which happens if PF tries to parse an inverse query) |
| 152 | // leads to an error in SMW - just exit if that's the case. |
| 153 | if ( strpos( $this->mSemanticProperty, '-' ) === 0 ) { |
| 154 | return; |
| 155 | } |
| 156 | |
| 157 | $proptitle = Title::makeTitleSafe( SMW_NS_PROPERTY, $this->mSemanticProperty ); |
| 158 | if ( $proptitle === null ) { |
| 159 | return; |
| 160 | } |
| 161 | |
| 162 | $store = PFUtils::getSMWStore(); |
| 163 | // this returns an array of objects |
| 164 | $allowed_values = PFValuesUtils::getSMWPropertyValues( $store, $proptitle, "Allows value" ); |
| 165 | if ( empty( $allowed_values ) ) { |
| 166 | $allowed_values = PFValuesUtils::getSMWPropertyValues( $store, $proptitle, "Allows value list" ); |
| 167 | } |
| 168 | $label_formats = PFValuesUtils::getSMWPropertyValues( $store, $proptitle, "Has field label format" ); |
| 169 | $propValue = \SMW\DIProperty::newFromUserLabel( $this->mSemanticProperty ); |
| 170 | $this->mPropertyType = $propValue->findPropertyTypeID(); |
| 171 | |
| 172 | foreach ( $allowed_values as $allowed_value ) { |
| 173 | // HTML-unencode each value |
| 174 | $wiki_value = html_entity_decode( $allowed_value ); |
| 175 | $this->mPossibleValues[] = $wiki_value; |
| 176 | if ( count( $label_formats ) > 0 ) { |
| 177 | $label_format = $label_formats[0]; |
| 178 | $prop_instance = \SMW\DataValueFactory::findTypeID( $this->mPropertyType ); |
| 179 | $label_value = \SMW\DataValueFactory::newTypeIDValue( $prop_instance, $wiki_value ); |
| 180 | $label_value->setOutputFormat( $label_format ); |
| 181 | $this->mValueLabels[$wiki_value] = html_entity_decode( $label_value->getWikiValue() ); |
| 182 | } |
| 183 | } |
| 184 | |
| 185 | // HACK - if there were any possible values, set the property |
| 186 | // type to be 'enumeration', regardless of what the actual type is |
| 187 | if ( count( $this->mPossibleValues ) > 0 ) { |
| 188 | $this->mPropertyType = 'enumeration'; |
| 189 | } |
| 190 | } |
| 191 | |
| 192 | /** |
| 193 | * Called if a matching property is found for a template field when |
| 194 | * a template is parsed during the creation of a form. |
| 195 | * @param string $semantic_property |
| 196 | */ |
| 197 | function setSemanticProperty( $semantic_property ) { |
| 198 | $this->mSemanticProperty = str_replace( '\\', '', $semantic_property ); |
| 199 | $this->mPossibleValues = []; |
| 200 | // set field type and possible values, if any |
| 201 | $this->setTypeAndPossibleValues(); |
| 202 | } |
| 203 | |
| 204 | /** |
| 205 | * Equivalent to setSemanticProperty(), but called when using Cargo |
| 206 | * instead of SMW. |
| 207 | * @param string $tableName |
| 208 | * @param string $fieldName |
| 209 | * @param CargoFieldDescription|null $fieldDescription |
| 210 | */ |
| 211 | function setCargoFieldData( $tableName, $fieldName, $fieldDescription = null ) { |
| 212 | $this->mCargoTable = $tableName; |
| 213 | $this->mCargoField = $fieldName; |
| 214 | |
| 215 | if ( $fieldDescription === null ) { |
| 216 | $fieldDescription = PFUtils::getCargoFieldDescription( $tableName, $fieldName ); |
| 217 | if ( $fieldDescription == null ) { |
| 218 | return; |
| 219 | } |
| 220 | } |
| 221 | |
| 222 | // We have some "pseudo-types", used for setting the correct |
| 223 | // form input. |
| 224 | if ( $fieldDescription->mAllowedValues != null ) { |
| 225 | if ( $fieldDescription->mIsHierarchy == true ) { |
| 226 | $this->mFieldType = 'Hierarchy'; |
| 227 | $this->mHierarchyStructure = $fieldDescription->mHierarchyStructure; |
| 228 | } else { |
| 229 | $this->mFieldType = 'Enumeration'; |
| 230 | } |
| 231 | $this->mRealFieldType = $fieldDescription->mType; |
| 232 | } elseif ( $fieldDescription->mType == 'Text' && $fieldDescription->mSize != '' && $fieldDescription->mSize <= 100 ) { |
| 233 | $this->mFieldType = 'String'; |
| 234 | } else { |
| 235 | $this->mFieldType = $fieldDescription->mType; |
| 236 | } |
| 237 | $this->mIsList = $fieldDescription->mIsList; |
| 238 | $this->mDelimiter = $fieldDescription->getDelimiter(); |
| 239 | $this->mPossibleValues = $fieldDescription->mAllowedValues; |
| 240 | $this->mIsMandatory = $fieldDescription->mIsMandatory; |
| 241 | $this->mIsUnique = $fieldDescription->mIsUnique; |
| 242 | $this->mRegex = $fieldDescription->mRegex; |
| 243 | } |
| 244 | |
| 245 | function getFieldName() { |
| 246 | return $this->mFieldName; |
| 247 | } |
| 248 | |
| 249 | function getValueLabels() { |
| 250 | return $this->mValueLabels; |
| 251 | } |
| 252 | |
| 253 | function getLabel() { |
| 254 | return $this->mLabel; |
| 255 | } |
| 256 | |
| 257 | function getSemanticProperty() { |
| 258 | return $this->mSemanticProperty; |
| 259 | } |
| 260 | |
| 261 | function getPropertyType() { |
| 262 | return $this->mPropertyType; |
| 263 | } |
| 264 | |
| 265 | function getExpectedCargoField() { |
| 266 | if ( $this->mCargoField != '' ) { |
| 267 | return $this->mCargoField; |
| 268 | } else { |
| 269 | return str_replace( ' ', '_', $this->mFieldName ); |
| 270 | } |
| 271 | } |
| 272 | |
| 273 | function getFullCargoField() { |
| 274 | if ( $this->mCargoTable == '' || $this->mCargoField == '' ) { |
| 275 | return null; |
| 276 | } |
| 277 | return $this->mCargoTable . '|' . $this->mCargoField; |
| 278 | } |
| 279 | |
| 280 | function getFieldType() { |
| 281 | return $this->mFieldType; |
| 282 | } |
| 283 | |
| 284 | function getRealFieldType() { |
| 285 | return $this->mRealFieldType; |
| 286 | } |
| 287 | |
| 288 | function getPossibleValues() { |
| 289 | if ( $this->mPossibleValues == null ) { |
| 290 | return []; |
| 291 | } |
| 292 | return $this->mPossibleValues; |
| 293 | } |
| 294 | |
| 295 | function getHierarchyStructure() { |
| 296 | return $this->mHierarchyStructure; |
| 297 | } |
| 298 | |
| 299 | function isList() { |
| 300 | return $this->mIsList; |
| 301 | } |
| 302 | |
| 303 | function getDelimiter() { |
| 304 | return $this->mDelimiter; |
| 305 | } |
| 306 | |
| 307 | function getDisplay() { |
| 308 | return $this->mDisplay; |
| 309 | } |
| 310 | |
| 311 | function getNSText() { |
| 312 | return $this->mNSText; |
| 313 | } |
| 314 | |
| 315 | function getNamespace() { |
| 316 | return $this->mNamespace; |
| 317 | } |
| 318 | |
| 319 | function getCategory() { |
| 320 | return $this->mCategory; |
| 321 | } |
| 322 | |
| 323 | function getForm() { |
| 324 | // @todo - add alternate forms here too. |
| 325 | if ( $this->mForm !== null ) { |
| 326 | return $this->mForm; |
| 327 | } |
| 328 | |
| 329 | $defaultFormForNamespace = PFFormLinker::getDefaultFormForNamespace( $this->mNamespace ); |
| 330 | if ( $defaultFormForNamespace !== null ) { |
| 331 | $this->mForm = $defaultFormForNamespace; |
| 332 | return $defaultFormForNamespace; |
| 333 | } |
| 334 | |
| 335 | if ( $this->mCategory != null ) { |
| 336 | $categoryPage = Title::makeTitleSafe( NS_CATEGORY, $this->mCategory ); |
| 337 | $defaultFormForCategory = PFFormLinker::getDefaultForm( $categoryPage ); |
| 338 | if ( $defaultFormForCategory !== null ) { |
| 339 | $this->mForm = $defaultFormForCategory; |
| 340 | return $defaultFormForCategory; |
| 341 | } |
| 342 | } |
| 343 | |
| 344 | return null; |
| 345 | } |
| 346 | |
| 347 | function isMandatory() { |
| 348 | return $this->mIsMandatory; |
| 349 | } |
| 350 | |
| 351 | function isUnique() { |
| 352 | return $this->mIsUnique; |
| 353 | } |
| 354 | |
| 355 | function getRegex() { |
| 356 | return $this->mRegex; |
| 357 | } |
| 358 | |
| 359 | function getHoldsTemplate() { |
| 360 | return $this->mHoldsTemplate; |
| 361 | } |
| 362 | |
| 363 | function setLabel( $label ) { |
| 364 | $this->mLabel = $label; |
| 365 | } |
| 366 | |
| 367 | function setNamespace( $namespace ) { |
| 368 | $this->mNSText = PFUtils::getCanonicalName( $namespace ); |
| 369 | $this->mNamespace = $namespace; |
| 370 | } |
| 371 | |
| 372 | function setNSText( $nsText ) { |
| 373 | $this->mNSText = $nsText; |
| 374 | // Translate from text to ID. |
| 375 | $dummyTitle = Title::newFromText( $nsText . ':ABC' ); |
| 376 | $this->mNamespace = $dummyTitle->getNamespace(); |
| 377 | } |
| 378 | |
| 379 | function setFieldType( $fieldType ) { |
| 380 | $this->mFieldType = $fieldType; |
| 381 | |
| 382 | if ( $fieldType == 'File' ) { |
| 383 | $this->mNSText = PFUtils::getCanonicalName( NS_FILE ); |
| 384 | $this->mNamespace = NS_FILE; |
| 385 | } |
| 386 | } |
| 387 | |
| 388 | function setPossibleValues( $possibleValues ) { |
| 389 | $this->mPossibleValues = $possibleValues; |
| 390 | } |
| 391 | |
| 392 | function setHierarchyStructure( $hierarchyStructure ) { |
| 393 | $this->mHierarchyStructure = $hierarchyStructure; |
| 394 | } |
| 395 | |
| 396 | function createText( $cargoInUse ) { |
| 397 | $fieldProperty = $this->mSemanticProperty; |
| 398 | // If this field is meant to contain a list, and the field has |
| 399 | // an associated SMW property, add on an 'arraymap' function, |
| 400 | // which will call the property tag on every element in the |
| 401 | // list. If, on the other hand, it uses Cargo, use #arraymap |
| 402 | // just for the link - but only if it's of type "Page". |
| 403 | if ( $this->mIsList && ( $fieldProperty != '' || |
| 404 | ( $cargoInUse && $this->mFieldType == 'Page' ) ) ) { |
| 405 | // Find a string that's not in the property |
| 406 | // name, to be used as the variable. |
| 407 | // Default is "x" - also use this if all the attempts fail. |
| 408 | $var = "x"; |
| 409 | if ( strstr( $fieldProperty, $var ) ) { |
| 410 | $var_options = [ 'y', 'z', 'xx', 'yy', 'zz', 'aa', 'bb', 'cc' ]; |
| 411 | foreach ( $var_options as $option ) { |
| 412 | if ( !strstr( $fieldProperty, $option ) ) { |
| 413 | $var = $option; |
| 414 | break; |
| 415 | } |
| 416 | } |
| 417 | } |
| 418 | $text = "{{#arraymap:{{{" . $this->mFieldName . '|}}}|' . $this->mDelimiter . "|$var|[["; |
| 419 | if ( $fieldProperty == '' ) { |
| 420 | $text .= "$var]]"; |
| 421 | } elseif ( $this->mNamespace == 0 ) { |
| 422 | $text .= "$fieldProperty::$var]]"; |
| 423 | } else { |
| 424 | $text .= $this->mNamespace . ":$var]] {{#set:" . $fieldProperty . "=$var}} "; |
| 425 | } |
| 426 | // If the delimiter isn't a comma, use that as the "new delimiter" as well. |
| 427 | if ( $this->mDelimiter !== ',' ) { |
| 428 | $text .= '|' . $this->mDelimiter . '\s'; |
| 429 | } |
| 430 | // Close #arraymap call. |
| 431 | $text .= "}}\n"; |
| 432 | return $text; |
| 433 | } |
| 434 | |
| 435 | // Not a list. |
| 436 | $fieldParam = '{{{' . $this->mFieldName . '|}}}'; |
| 437 | if ( $this->mNamespace == 0 ) { |
| 438 | $fieldString = $fieldParam; |
| 439 | } else { |
| 440 | $fieldString = $this->mNamespace . ':' . $fieldParam; |
| 441 | } |
| 442 | |
| 443 | if ( $fieldProperty == '' ) { |
| 444 | if ( $cargoInUse && ( $this->mFieldType == 'Page' || $this->mFieldType == 'File' ) ) { |
| 445 | $fieldString = "[[$fieldString]]"; |
| 446 | // Add an #if around the link, to prevent |
| 447 | // anything from getting displayed on the |
| 448 | // screen for blank values, if the |
| 449 | // ParserFunctions extension is installed. |
| 450 | if ( ExtensionRegistry::getInstance()->isLoaded( 'ParserFunctions' ) ) { |
| 451 | $fieldString = "{{#if:$fieldParam|$fieldString}}"; |
| 452 | } |
| 453 | return $fieldString; |
| 454 | } |
| 455 | return $fieldString; |
| 456 | } elseif ( $this->mNamespace == 0 ) { |
| 457 | return "[[$fieldProperty::$fieldString]]"; |
| 458 | } else { |
| 459 | // Special handling is needed, for at |
| 460 | // least the File and Category namespaces. |
| 461 | return "[[$fieldString]] {{#set:$fieldProperty=$fieldString}}"; |
| 462 | } |
| 463 | } |
| 464 | |
| 465 | } |