SLB: Notes – JS: Components: Themes: Layout Tags
Requirements
- Insert predefined HTML
- Core and theme-specific
- Support dynamic content
- Changes on per-item basis
- Necessary to support multiple content types (e.g. images in
<img>
element, HTML in<div>
, etc.) - Support attributes/options
- Customize how tag is processed/output
- Support user-customizable options (UI labels, formatting, etc.)
Elements (Core)
- Content: Primary content (image, video, etc.) displayed in lightbox
- Dynamic: HTML changes based on content type
- Item Data: Data/attributes of current item
- Examples: Permalink, source URI, image dimensions, title, caption, description, etc.
- Available attributes based on item’s content type
- Common attributes
- Source URI (
string
): Direct URI to content (for display in lightbox) - Image source, video file, etc.
- Permalink (
string
): Canonical URI for content (e.g. when viewed on its own page) - Video page, attachment page, image URI, Website address, etc.
- Title (
string
): Item caption - Derived from link if not otherwise available
- Group (
obj
): Group item belongs to - Internal (
bool
): Whether item is internal media or not - UI elements
- Static: Does not change per-item
- Labels: User-customizable UI content
- Navigation text: previous/next item, start/stop slideshow, close, etc.
- Predefined elements: HTML for building UI (close button, prev/next button, loading indicator, etc.)
Implementation
- Dynamic Data (options)
- Wrap tag output with DOM element
- Example:
<span id="slb_tag-id" class="slb_dynamic_wrap">[tag output]</span>
- Wrapper indicates dynamic data using DOM attributes
class
:slb_dynamic_wrap
id
:slb_tag[id]
(Points to object with tag options)- Alternative: Set reference to raw tag as data on wrapper element itself
$(el).data('slb_tag', tag);
+
Allows dynamic replacement of content in viewer- Similar to current method of loading new content in lightbox (replace HTML inside of a wrapper DOM element)
+
Allows any tag to be dynamic?
Should all tags be dynamic?A
: No, only those accessing data (item, environment, date/time, etc.)-
Cannot use data within HTML tags (since tag output is wrapped in a DOM element itself)- Example
Original<a href="domain.com/file.html?id={tag}">Link text</a>
Rendered
<a href="domain.com/file.html?id=<span id="slb_tag-id">[tag output]</span>">Link text</a>
- Solution (options)
- Build HTML tag using options in theme tag
- Example
- Link
<a href="domain.com/file.html?id=[tag data]">Link text</a>
- Tag
{tag pre='<a href="domain.com/file.html?id=' post='">Link text</a>'}
- Alt
{tag format='<a href="domain.com/file.html?id=%s">Link text</a>'}
- Uses string formatting to replace
%s
with tag output - Entire output wrapped in wrapper
- Original string format saved
- Formatted value inserted as HTML into DOM (wrapped)
+
Allows complex output using item data+
Does not impede HTML output-
Convoluted way to build HTML output using tag output-
Limited: How to use other data within link? (link text,title
attribute, etc.)- Register handlers for different tags
- Similar to CNR content type field templates
- Example: Link
{link href="domain.com/file.html?id=%s" data="item.permalink"}Link text{/link}
- Attributes
href
: URI formatdata
: Data to use in URI formattitle
: Link title (can be string format)title_data
: Data to use for Link title- Link text: Wrapped in tag
+
More specific handling of output- Attribute data will be properly formatted (escaped for URLs, etc.)
+
Simple: Don’t need to mess with HTML in tag attributes-
More complex to implement+
Highly flexible: any kind of output can be accomplished by tag handlers- Rebuild entire layout for each item
- Start with raw layout (with tags, etc.) every time an item is displayed
-
Inefficient: must parse entire layout for each item (even if few dynamic tags are present)- Performance may suffer
+
Will always be a certain amount of dynamic data in layout (content, etc.)- Parts of layout must always be rebuilt per-item anyway
?
Visual smoothness? Rebuilding full layout affect transition between items?- Likely
+
Simple: Don’t need to wrap tags since raw layout will be used every time- Tags (Default)
item
: Access item data/properties- Example:
{item.title}
– Item title - Dynamic: Yes
- Format modifiers: Yes
{item.title|lower|escape}
(makes item title lowercase and escapes it)ui
: User interface output- Example:
{ui.nav_next}
– Next item navigation link - Dynamic: No
- Format modifiers: No
- Common attributes: Can be set on all default tags
- May be implemented differently by different tags
class
: CSS classid
: Unique ID- Tag format (Options)
- Curly braces + XML-style attributes
- Tags denoted by curly braces (
{
,}
) - Options/attributes set XML-style:
attribute="value"
+
Simple: Familiar to any using HTML+
Fairly unique: Curly braces not common in normal content?
How do format modifiers fit in?- Simple:
{tag.prop|modifier}
- With Options
- XML-style attributes followed by delimited modifiers:
{tag.prop attribute="value"|modifier}
- Attributes processed first, then passed to modifiers
+
Clear separate between modifiers and attributes+
Still pretty simple to write-
Convoluted: 2 different modes for similar information (options that modify output)- Format modifier style:
{tag.prop|attribute:value|modifier}
-
Attributes not clearly separated from modifiers (hard to tell when option is an attribute or a modifier)+
Simple: Singular way to add options that modify output+
Tag handler can use supported options and pass output to global modifiers after (with processed options removed)supports_modifiers
flag in tag definition can determine whether output is processed by global modifiers or not- One or the other (attributes or modifiers):
{tag.prop attribute="value"}
or{tag.prop|modifier}
-
Limiting: May be useful to have access to properties and modifiers in tag?
When? (Use cases)- Item: No – Modifiers only (
{item.title|lower}
) - UI: No – Attributes only (
{ui.nav_next class="test"}
) - Outputs DOM element, so should not be modified by standard modifiers (
lower
, etc.) - Formatting of values (e.g. labels) should be handled via CSS
- Custom Tags: Possibly (
{tag attr="value"|modifier}
) +
Allows theme designer to further customize output from custom tags- Double braces (curly/square) + XML-style attributes
- Attributes same as 1
- Tags denoted by double braces (
{{
/}}
or[[
/]]
) +
More unique: double braces even less common than single braces in content-
More characters to type for every tag-
Increases visual “noise” in layout- Other established format
- Liquid, Smarty, etc.
- Need to look into options
- Registering External Tag Handlers (options)
- Client file registration (via other plugins)
- Allow additional files to be registered with internal client files
- Use same structure:
[handle, file, etc.]
-
Will need to expand file parser to handle external files+
Not too difficult since external files should have full path rather than relative path (just look for presence of path constants)+
Allows simple inclusion of JS files after internal files loaded- JS file can register tags, etc.
- Use dependencies to determine order of loading external files
+
Also controls whether external file is loaded (if dependent on internal file that is not loaded, external file with not be loaded, etc.)- WP Hooks
- Fire hooks before/after various operations
- Events
slb_head
/slb_admin_head
: Header files loadedslb_footer
/slb_admin_footer
: Footer files loadedslb_client_init
: Client JS initialized+
Allows external code to add files/code in proper location- Ensures SLB’s files are loaded before external code is executed
?
How to confirm necessary files have been loaded?- Hooks will always fire, but different files are loaded based on various conditions (context, callbacks, etc.)
A
Use SLB functions in external code to determine if external file should be loaded- PHP
/* External Plugin */ add_action('slb_head', 'ext_load_head_files'); function ext_load_head_files() { if ( slb_is_enabled() && slb_is_context('public') ) { //Load files... } }
- JS (object detection)
/* Confirm SLB loaded */ if ( !SLB || !SLB.View ) return false; /* Run code */ SLB.View.add_tag(...);
?
How to fire hook after files loaded?- File loading is handled by WP enqueue/registration API (No direct loading)
A
Add hook to trigger SLB hook//Low priority hook add_action('wp_head', 'call_slb_head', 99); function call_slb_head() { //Fire internal hook do_action('slb_head'); }
- Tag Handlers
- Properties
id
(string
): Tag IDbuild
(function
): Function to build tag outputattrs
(object
): Default attributes/valuesdynamic
(bool
): Tag rebuilt for each item or notsupports_modifiers
(bool
): Determines if modifiers can be used on tag output