Widget - lstpsche/webring-rails GitHub Wiki

The Webring Widget is a key component that allows member sites to display a navigation interface for the webring.

Widget.js

The widget.js file is a standalone JavaScript snippet that creates a navigation widget on member sites. It's designed to be easily embedded with a single script tag and offers various customization options.

How to Use the Widget

To add the webring widget to a member's site, include the following code:

<!-- Webring Widget -->
<script src='https://yourhub.com/widget.js' data-member-uid='MEMBER_UID'></script>
<div id='webring-widget'></div>
<!-- End Webring Widget -->

Replace https://yourhub.com with your application's domain and MEMBER_UID with the member's unique identifier.

Widget Customization Options

The widget can be customized through data attributes on the script tag:

Widget Type (data-widget-type)

  • full: Text, back button, random button, forward button (default)
  • no-text: Back button, random button, forward button (no text)
  • two-way: Back and forward buttons (no random)
  • one-way: Forward button only
  • random-only: Random button only

Button Text (data-button-text)

  • true: Show text labels on buttons (default)
  • false: Show only symbols (no text)

Styling (data-styles)

  • full: Apply all styles (default)
  • layout: Only layout styles, no visual design
  • none: No styles applied

Target Element (data-target-id)

  • Sets a custom ID for the target container (default: webring-widget)

Theme Options

  • data-theme: Sets the visual theme for the widget
    • light: Light theme with white background and black text (default)
    • dark: Dark theme with black background and white text

Custom Text Options

  • data-prev-text: Sets custom text for the "previous" button (default: "Prev")
  • data-random-text: Sets custom text for the "random" button (default: "Random")
  • data-next-text: Sets custom text for the "next" button (default: "Next")
  • data-widget-text: Sets custom text for the widget title (default: "Webring")

Example With All Options

<script src='https://yourhub.com/widget.js'
        data-member-uid='MEMBER_UID'
        data-widget-type='full'
        data-button-text='true'
        data-styles='full'
        data-theme='dark'
        data-target-id='custom-widget-id'
        data-prev-text='Previous'
        data-random-text='Surprise Me'
        data-next-text='Forward'
        data-widget-text='My Webring'></script>
<div id='custom-widget-id'></div>

Multiple Widgets on the Same Page

You can include multiple widgets on the same page by specifying different target IDs:

<!-- First Widget -->
<script src='https://yourhub.com/widget.js'
        data-member-uid='MEMBER_UID'
        data-widget-type='full'
        data-target-id='webring-widget-1'></script>
<div id='webring-widget-1'></div>

<!-- Second Widget -->
<script src='https://yourhub.com/widget.js'
        data-member-uid='MEMBER_UID'
        data-widget-type='no-text'
        data-target-id='webring-widget-2'></script>
<div id='webring-widget-2'></div>

Member-side Widget Style Customization

Members can customize the widget's appearance beyond the built-in themes by overriding CSS custom properties (CSS variables) in their own stylesheets. This provides fine-grained control over colors, backgrounds, and other visual aspects while maintaining compatibility with the widget's structure.

Note

CSS variable customization is meant to be used by member sites.

Available CSS Variables

The widget exposes the following CSS custom properties that members can override:

Background and Layout

  • --webring-theme-bg: Main widget background color
  • --webring-theme-border: Border color for the widget container (full widget type only)
  • --webring-theme-text: Color for the widget title text

Button Styling

  • --webring-theme-btn-bg: Button background color
  • --webring-theme-btn-border: Button border color
  • --webring-theme-btn-text: Button text color
  • --webring-theme-btn-hover-bg: Button background color on hover/active states
  • --webring-theme-btn-hover-text: Button text color on hover/active states
  • --webring-theme-font-family: Font family for the widget

How to Override Variables

Members can add custom CSS to their site to override these variables. The approach depends on whether you want to support both themes or just the light theme:

Light Theme Only

If you only want to support the light theme, you can use the basic .webring-nav selector:

/* Custom widget styling - light theme only */
.webring-nav {
  --webring-theme-bg: #f0f8ff;
  --webring-theme-border: #4169e1;
  --webring-theme-text: #191970;
  --webring-theme-btn-bg: #ffffff;
  --webring-theme-btn-border: #4169e1;
  --webring-theme-btn-text: #4169e1;
  --webring-theme-btn-hover-bg: #4169e1;
  --webring-theme-btn-hover-text: #ffffff;
  --webring-theme-font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
}

Important

Using just .webring-nav will not override dark theme variables due to CSS specificity. The dark theme selector .webring-nav[data-theme="dark"] has higher specificity and will take precedence.

Supporting Both Themes

If you want to support both light and dark themes, you must use the data-theme attribute selectors to ensure proper CSS specificity:

/* Custom light theme styling */
.webring-nav[data-theme="light"] {
  --webring-theme-bg: #fff8dc;
  --webring-theme-border: #daa520;
  --webring-theme-text: #8b4513;
}

/* Custom dark theme styling */
.webring-nav[data-theme="dark"] {
  --webring-theme-bg: #2f2f2f;
  --webring-theme-border: #87ceeb;
  --webring-theme-text: #f0f8ff;
}

Complete Customization Example

Here's a complete example showing how a member might customize their widget to match their site's branding:

<!-- In the member's HTML -->
<script src='https://yourhub.com/widget.js'
        data-member-uid='MEMBER_UID'
        data-widget-type='full'
        data-theme='light'></script>
<div id='webring-widget'></div>

<!-- In the member's CSS -->
<style>
.webring-nav {
  /* Custom brand colors */
  --webring-theme-bg: #fef7e0;
  --webring-theme-border: #f59e0b;
  --webring-theme-text: #92400e;
  --webring-theme-btn-bg: #fbbf24;
  --webring-theme-btn-border: #f59e0b;
  --webring-theme-btn-text: #92400e;
  --webring-theme-btn-hover-bg: #f59e0b;
  --webring-theme-btn-hover-text: #ffffff;
  --webring-theme-font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
}
</style>

CSS Specificity Notes

  • Member CSS variables will override the widget's default theme variables
  • Use standard CSS specificity rules if you need to ensure your customizations take precedence
  • The widget's CSS is inserted at the beginning of the <head> to allow member styles to override it easily

Customizing the Widget Controller

The Webring Widget can be further customized on the server-side by creating a custom widget controller in your application.

Available Customizations

The widget controller supports several customization options:

  • Logo replacement: Customize the widget logo with your own SVG
  • Default text customization: Override default button and title texts
  • Metrics tracking: Enable widget usage analytics

Logo Customization

You can replace the default widget logo with your own SVG:

  1. Generate a custom widget controller:
rails generate webring:custom_widget_controller
  1. This will create a new controller at app/controllers/webring/custom_widget_controller.rb with a template for logo customization (see Custom Widget Controller):

  2. Replace the SVG content with your own custom logo.

Important

Your custom SVG must include the ${width}, ${height}, and ${style} placeholders which will be dynamically replaced when the widget is rendered. This will allow the widget to control the logo's dimensions and layout styling.

  1. The generator will automatically update your routes to use the custom controller.

Default Text Customization

You can also override the default texts used in the widget through your custom widget controller.

After generating your custom widget controller, you can override the #text_defaults method to customize the default texts:

# app/controllers/webring/custom_widget_controller.rb
class Webring::CustomWidgetController < Webring::WidgetController
  # Provide default texts for the widget
  # Override this method to customize the default texts
  def text_defaults
    {
      prev: { default: 'Prev', enforced: false },
      random: { default: 'Random', enforced: false },
      next: { default: 'Next', enforced: false },
      widgetTitle: { default: 'Webring', enforced: false }
    }
  end
end

These default texts will be used when a member site doesn't specify custom text via data attributes.

If any entry is missing, the gem's default texts will be used for that entry.

Note

The enforced flag is used to determine if the default text should be enforced over any client-side customization via data attributes. Meaning, if the enforced flag is true, the default text will be used even if the client-side customization is provided. Thus, making your customization webring-wide.

Metrics Tracking

The widget controller supports optional metrics tracking to monitor widget usage across member sites. When enabled, the widget will automatically send a POST request to your metrics endpoint whenever it's loaded on a member site.

Enabling Metrics Tracking

To enable metrics tracking, override the widget_fetch_metrics_path method in your custom widget controller:

# app/controllers/webring/custom_widget_controller.rb
class Webring::CustomWidgetController < Webring::WidgetController
  private

  def widget_fetch_metrics_path
    '/webring/metrics/widget_fetched'
  end
end

How Metrics Tracking Works

When a metrics path is provided:

  1. Automatic tracking: The widget automatically sends a POST request when loaded
  2. Member identification: The request includes the member's UID for identification
  3. Silent failure: If the metrics endpoint is unavailable, the widget continues to function normally
  4. No user impact: Metrics tracking doesn't affect widget functionality or user experience

Request Format

The metrics request is sent as JSON with the following structure:

{
  "uid": "member_unique_identifier"
}

Implementing a Metrics Endpoint

You'll need to create a controller and route to handle the metrics data:

# app/controllers/metrics_controller.rb
class MetricsController < ApplicationController
  skip_forgery_protection only: [:widget_fetched]

  def widget_fetched
    member_uid = params[:uid]

    # Process the metrics data as needed
    # Example: increment a counter, log to analytics, etc.

    head :ok
  end
end

# config/routes.rb
post '/webring/metrics/widget_fetched', to: 'metrics#widget_fetched'

Tip

By default, the base Webring::WidgetController returns nil for widget_fetch_metrics_path, which disables metrics tracking. Only override this method if you want to enable metrics collection.

⚠️ **GitHub.com Fallback** ⚠️