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_wrapid: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
%swith 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,titleattribute, 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_modifiersflag 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.)
AUse 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)
AAdd 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