1 /** 2 * Copyright © Webd 2018 3 * License: MIT (https://github.com/DiamondMVC/Webd/blob/master/LICENSE) 4 * Author: Jacob Jensen (bausshf) 5 */ 6 module webd.web.tagcollection; 7 8 import std.variant : Variant; 9 10 import webd.web.loop; 11 12 /// Wrapper around a tag collection. 13 class TagCollection(string tagName = "tags") 14 { 15 private 16 /// The tags of the collection. 17 Variant[string] _values; 18 /// An inner collection of tags. 19 TagCollection!tagName _tags; 20 21 public: 22 @property 23 { 24 /// Gets the keys of the tags. 25 auto keys() { return _values.keys; } 26 } 27 28 /** 29 * Adds a tag to the collection. 30 * Params: 31 * key = The key of the tag. 32 * value = The value of the tag. 33 */ 34 void add(T = string)(string key, T value) 35 { 36 _values[key] = value; 37 } 38 39 /** 40 * Removes a tag from the collection. 41 * Params: 42 * key = The key of the tag. 43 */ 44 void remove(string key) 45 { 46 if (_values) 47 { 48 _values.remove(key); 49 } 50 } 51 52 /** 53 * Checks whether a key exist in the collection or not. 54 * Params: 55 * key = The key to check for existence. 56 * Returns: 57 * Returns true if the key exist, false otherwise. 58 */ 59 bool has(string key) 60 { 61 return _values && key in _values; 62 } 63 64 /** 65 * Gets the value of a tag in the collection. 66 * Params: 67 * name = The name of the tag. 68 * defaultValue = The default value to return if the tag doesn't exist. 69 * Returns: 70 * The value of the tag, else the default value. 71 */ 72 T get(T = string)(string name, lazy T defaultValue = T.init) 73 { 74 if (!_values) 75 { 76 return defaultValue; 77 } 78 79 import std.variant : Variant; 80 Variant value = _values.get(name, Variant.init); 81 82 if (!value.hasValue) 83 { 84 return defaultValue; 85 } 86 87 return value.get!T; 88 } 89 90 /* 91 * Gets a loop from the collection. 92 * Params: 93 * name = The name of the loop. 94 * Returns: 95 * The loop if existing, else an empty loop range. 96 */ 97 Loop getLoop(string name) 98 { 99 return get!Loop(name); 100 } 101 102 /// Clears all tags. 103 void clearTags() 104 { 105 if (_values) 106 { 107 _values.clear(); 108 } 109 } 110 111 /** 112 * Clears tags based on a tag prefix ex. "page::", "item::" etc. 113 * Params: 114 * tagPrefix = The tag prefix. 115 */ 116 void clearTags(string tagPrefix) 117 { 118 import std.algorithm : startsWith; 119 120 string[] keysToRemove; 121 122 foreach (key; keys) 123 { 124 if (key.startsWith(tagPrefix)) 125 { 126 keysToRemove ~= key; 127 } 128 } 129 130 foreach (keyToRemove; keysToRemove) 131 { 132 _values.remove(keyToRemove); 133 } 134 } 135 136 /// Creates an inner tag collection. 137 void createTags() 138 { 139 _tags = new TagCollection!tagName; 140 } 141 142 @property 143 { 144 /// Gets the inner tag collection. 145 mixin("TagCollection " ~ tagName ~ "() { return _tags; }"); 146 } 147 }