Tool Options for the Design System

Mike's Notes

I need to determine what third-party design and management software to use and how to integrate it with the Ajabbi Design System.

This is for both future customers and the Ajabbi team.

These notes came from Vitaly Friedman, editor of Smashing Magazine, a fantastic resource.

Resources

  • Resource

References

  • Reference

Repository

  • Home > Ajabbi Research > Library >
  • Home > Handbook > 

Last Updated

17/04/2025

Tool Options for the Design System 

By: Vitaly Friedman
Smashing Magazine: 22/06/2024

Requirements

Needs to work with design tokens.

Options

  • Figma
  • Token Studio
  • SuperNova

Figma

Notes

"Figma is a collaborative web application for interface design, with additional offline features enabled by desktop applications for macOS and Windows. The feature set of Figma focuses on user interface and user experience design, with an emphasis on real-time collaboration, utilising a variety of vector graphics editor and prototyping tools. The Figma mobile app for Android and iOS allows viewing and interacting with Figma prototypes in real-time on mobile and tablet devices." - Wikipedia

Pricing

  • Starter (free)
  • Professional ($15/m per seat)
  • Organisation ($45/m per seat)
  • Enterprise ($75/m per seat)

Resources

Token Studio

Notes

Tokens Studio for Figma is a Figma Plugin allowing you to integrate Tokens into your Figma designs.

It gives you reusable tokens that can be used for a whole range of design options, from border radius or spacer units to semantic color and typography styles. It allows you to change tokens and see these changes applied to the whole document or its styles. - Token Studio

Pricing

  • Free (free)
  • Pro (19 Euro/m per user)

Resources

SuperNova

Notes

"Supernova connects your design and engineering data in a single design system tool to accelerate and scale your product development."

"Supernova manages the entire design system lifecycle in one place. It's designed to fit with the way your team already works — without changing tools or maintaining self-built workflows and integrations — to enable your team to build better products.

Connect Figma files to your Supernova design system, sync design tokens via our Tokens Studio integration, and import variables from Figma via our plugin to ensure you constantly have the most-up-to-date design data in your design system.

Create advanced documentation using this data to keep documentation in sync whenever changes are made. Finally, connect design and code by automating code delivery with code pipelines to deliver tokens, styles, icons, components and documentation to your codebases." - SuperNova

Pricing

  • Free (free)
  • Team ($45/m per seat)
  • Company ($75/m per seat)

Resources

Alternatives

Open-source

  • Penpot
  • Lunacy

Paid

  • Adobe XD
  • UXPin
  • Zeplin
  • LucidChart
  • Miro
  • Framer
  • AxureRP

The Ontolog Forum

Mike's Notes

Some years ago, while searching for examples of how to build temporal databases, I came across Dr. Matthew West. He had worked on and written about an approach called 4Dism. I discovered archives of his papers and articles to read.

Then I discovered he was a member of the Ontolog Forum, which looked very useful. So, I asked him if I could join. It has a rich Google Group

Resources

References

  • Reference

Repository

  • Home > Ajabbi Research > Library >
  • Home > Handbook > 

Last Updated

17/05/2025

The Ontolog Forum

By: Mike Peters
On a Sandy Beach: 21/06/2024

Mike is the inventor and architect of Pipi and the founder of Ajabbi.

Discussion Example


12/06/2024 Post

"Guys,

>> However, IMHO, If the model is a model of the “real world” then is it not a “data” model.  I would rather call things what they are: if it’s a “data model” you’re modelling data structures.  If you’re modelling the “real world” then it is not a “data” model – because it’s not a model of data.  (The term “conceptual data model” should be banished from everyone’s vocabulary!)  If you are modelling the real world, it could be called an “ontology”. 

Bill and I have been having a long conversation about this offline.

Bill is , of course, quite right about the mainstream orthodox view of modelling in the IS community. 
This envisages a starting point where one develops a model of the real world (the model represents/refers to the real world)
At some stage (the data modelling stage) one then uses exactly the same model as a data model to represent the data structure of the system you are building. Where, of course, some of the data then represents the real world - so a two level model. 

I have, in the last decade or so, come to think that there is a different and better way to describe what is going on - one that opens up new ways of working.

The kind of conceptual models we build using things like UML modelling tools, it seems to me, can be regarded as representing the real world, but also (at the same time) showing how this representation can be captured as data.
(For more on showing see Macbeth, D. (2012). Seeing How It Goes: Paper-and-Pencil Reasoning in Mathematical Practice. Philosophia Mathematica, 20(1), 58–85. https://doi.org/10.1093/philmat/nkr006)
So the shift from conceptual to data models can be seen as not a shift in representation but different roles for the same model - one of representing the other of showing.
And that during the SDLC this model evolves becoming a closer and closer match for how it shows the data in the system - and then (with modern MDA tools) it becomes the system.

Interestingly, this then gives these IS models a similar sense to models elsewhere, e.g. in architecture, where a scale model is built to show what the building would look like.
Also, closer to the sense of model in science that is explored by e.g. Margaret Morrison and Mary Morgan.

There is a lot more to say, but just two quick points.
If one is reverse engineering, so  travering the SDLC in the opposite direction, then this showing perspective is a much better match for the practice we follow in bCLEARer. So we start with a system and then we 'evolve' the whole system to one where the 'conceptual' underpinning (the real world representing) is much clearer and explicit. 
If one accepts that one is both representing the real world and showing the system, then the current practices of only modelling (representing and showing) entity types at the conceptual modelling stage seems odd - why not model the individual entities - the particulars. ..." - Chris Partridge

17/06/2024 Post

"Hi John and other interested parties,

There was a thread on this forum a while back that ultimately lead to my publication of a presentation titled “Understanding Data” to slideshare, which also has a safer PDF variantPDF variant on our website.

Basically, I defined data as observation in reusable form.b..." - Kingsley Idehen

How to target only IE (any version) within a stylesheet?

Mike's Notes

I need to make Ajabbi backwards-compatible with any old versions of IE that are still in use.

This is an issue with older people who have kept the same computer for 20 years and impoverished countries relying on old gear.

Getting the Content Management System (CMS) to do this is a minor issue. It's knowing what code to use. And here it is.

From StackOverflow some years ago.

Resources

References

  • Reference

Repository

  • Home > Ajabbi Research > Library >
  • Home > Handbook > 

Last Updated

18/04/2025

How to target only IE (any version) within a stylesheet?

By:
Stackoverflow: 09/02/2015

Internet Explorer 9 and lower:

You could use conditional comments to load an IE-specific stylesheet for any version (or combination of versions) that you wanted to target specifically, like the one below, using an external stylesheet.

<!--[if IE]>
  <link rel="stylesheet" type="text/css" href="all-ie-only.css" />
<![endif]-->

However, beginning in version 10, conditional comments are no longer supported in IE.

Internet Explorer 10 & 11:

Create a media query using -ms-high-contrast, where you place your IE 10 and 11-specific CSS styles. Because -ms-high-contrast is Microsoft-specific (and only available in IE 10+), it will only be parsed in Internet Explorer 10 and greater.

@media all and (-ms-high-contrast: none), (-ms-high-contrast: active) {
     /* IE10+ CSS styles go here */
    }
    
Microsoft Edge 12 :

Can use the @supports rule Here is a link with all the info about this rule.

@supports (-ms-accelerator:true) {
  /* IE Edge 12+ CSS styles go here */ 
}

Inline rule IE8 detection I have 1 more option but only detect IE8 and below version.

  /* For IE css hack */
  margin-top: 10px\9 /* apply to all ie from 8 and below */
  *margin-top:10px;  /* apply to ie 7 and below */
  _margin-top:10px; /* apply to ie 6 and below */

As you specified for an embedded stylesheet. I think you need to use media query and conditional comment for the below version.

Visual design rules you can safely follow every time

Mike's Notes

I came across this via Smashing Magazine. It has detailed CSS settings to use.

Resources

References

  • Reference

Repository

  • Home > Ajabbi Research > Library >
  • Home > Handbook > 

Last Updated

17/05/2025

Article

By: Mike Peters
On a Sandy Beach: 19/06/2024

Mike is the inventor and architect of Pipi and the founder of Ajabbi.

"You do not have to follow these rules every time. If you have a good reason to break any of them, do. But they are safe to follow every time. ..." - Anthony Hobday

Ten Things You Need to Know About Your Autistic Employee

Mike's Notes

Note

Resources

References

  • Reference

Repository

  • Home > Ajabbi Research > Library >
  • Home > Handbook > Teams > Disability

Last Updated

17/05/2024

Ten Things You Need to Know About Your Autistic Employee

By: Dr. Michelle Garnett and Professor Tony Attwood
Attwood & Garnett: 18/06/2024

By Dr. Michelle Garnett and Professor Tony Attwood

In today’s dynamic and diverse workplace, it is crucial to recognize the unique strengths and perspectives that neurodivergent individuals bring to the table. Autistic employees can be a tremendous asset to any organization, provided they are understood, supported, and valued. Here are ten important considerations for employers to keep in mind when interviewing and employing autistic individuals, grounded in research and a strengths-based approach.

Focus on Strengths, Not Stereotypes

Autistic individuals often possess exceptional abilities in various areas, such as single-minded focus, attention to detail, pattern recognition, and ethical and creative problem-solving. For example, many autistic people excel in roles that require precision and analytical thinking, others excel in the visual and dramatic arts, and others in the caring professions. They often have a strong moral compass, and are loyal, hard-working, committed, and compassionate. Recognizing and valuing these strengths in your autistic employee raises the bar for all employees.

Clear and Direct Communication

Clear, direct, and unambiguous communication is often the most effective way to interact with autistic individuals. Some autistic people find it challenging to interpret non-verbal cues or implied meanings, whilst others have made an art of it. Others find auditory information a struggle to quickly interpret and later remember. To enhance communication further for some, make it visual. Providing clear instructions and feedback will enhance understanding, performance and motivation.

Structured and Predictable Environment

Many people dislike change and uncertainty, but it is important to know that for an autistic person these are significant stressors. Thus, a structured work environment with predictable routines can help autistic employees thrive. Sudden changes or chaotic settings can interfere with work performance because they are so stressful. When possible, give advance notice of changes to schedules or tasks, and maintain a consistent work environment.

Sensory Considerations

Many autistic individuals are sensitive to sensory stimuli such as bright lights, loud noises, or strong smells. Be mindful of the sensory environment and make accommodations as needed. This might include offering noise-cancelling headphones, adjusting lighting, or providing a quiet, uncluttered workspace. Offering a retreat space where there is a very minimal sensory load can go a long way to assisting an autistic person to re-calibrate as needed throughout their working hours. Conduct a sensory assessment of the workplace with your employee and regularly check in to ensure that any adjustments are working.

Inclusive Interview Techniques

Traditional interview processes tend not to showcase the strengths of autistic candidates. Consider alternative interview methods such as practical assessments, work trials, or having an autistic interviewer on the panel. This allows candidates to demonstrate their abilities in a comfortable setting. If a candidate has disclosed their autism prior to interview, reach out to ask about any adjustments that help them feel more at ease, including sensory adjustments for the setting, like wearing a visor, or providing interview questions in advance.

Support for Social Interactions

Social interactions in the workplace can be challenging for both the autistic and non-autistic employees. Offer support, such as a mentor, to your autistic employees and organise training in autism for your nonautistic employees. Co-discover team-building activities that are inclusive and respectful of neurodiversity. For example, an autistic employee may not enjoy a weekend away with work colleagues with no space to recharge their battery in solitude, especially if the expectation is nonstop socialising.

Reasonable Accommodations

Under different legislation in different countries, employers are required to provide reasonable accommodations to autistic employees. These might include sensory accommodations as above, flexible work hours, remote work options, or specific tools and technologies. However, any accommodations are severely undermined when there is workplace stigma for asking for them or seeing them implemented. Organise training in autism for staff to debunk common myths and misconceptions and to teach about the realities of autism to directly fight negative stigma. Discuss openly with the employee to determine what accommodations are necessary for their success. Check in with other employees about their needs also, many accommodations for autistic people work very well for humans in general.

Focus on Connection and Well-being

Autistic individuals may be more prone to anxiety or stress, especially in a work environment that is not accommodating. A non-accommodating work environment tells the person that their concerns are not important, and even worse, not valid. Autistic people are very perceptive of emotional atmosphere. If they feel unsupported, they are likely to feel unsafe, and their well-being will be affected. Promote a culture of connection and well-being by offering resources such as a focus on healthy relationships at work that are driven by caring and respect, access to stigma-free counselling services as needed for all employees, stress management programmes, and creating a supportive, flexible work environment. All employees will benefit.

Professional Development Opportunities

Invest in the professional development of autistic employees. Provide opportunities for further training and career advancement. Recognize their potential for growth and offer pathways for them to enhance their skills and advance within the company. Autistic employees, like all employees, suffer stress when there are too many demands or too few. Many autistic people are driven, achievement-oriented, thrive on being challenged and love learning.

Create an Inclusive Culture

Fostering an inclusive workplace culture benefits everyone. Educate all employees about neurodiversity and the value it brings to the organization. Encourage empathy, respect, and understanding. Celebrate the contributions of autistic employees and ensure they feel valued and included.

Conclusion

Employing autistic individuals is not just about compliance with legal requirements; it is about embracing diversity and reaping the benefits of a diverse workforce. By understanding and accommodating the unique needs of autistic employees, employers can create a more inclusive, productive, and innovative workplace. This approach not only benefits autistic individuals but also enhances the overall organizational culture, leading to greater success and fulfillment for all employees.

Where to from here?

We have prepared a half-day training on autism, Autism Working, for employers, autistic and non-autistic employees, autistic people looking for work, and parents and family members. We will be discussing the advantages of autism in the workplace, common challenges, and ways to navigate the challenges successfully.

Reliably Processing Trillions of Kafka Messages Per Day

Mike's Notes

I discovered this by reading the Walmart Global Tech Blog (SubStack) by Ravinder Matte, 15/06/2024

Resources

References

  • Reference

Repository

  • Home > Ajabbi Research > Library >
  • Home > Handbook > 

Last Updated

17/05/2025

Reliably Processing Trillions of Kafka Messages Per Day

By: Ananth Packkildurai
Dtata Engineering Weekly 17/06/2024

Summary

Walmart deploys Apache Kafka, with 25K+ Kafka consumers, across multiple clouds (public and private). Supporting business critical use cases including data movement, event driven microservices and streaming analytics. These use-cases demand 4 nines (i.e., 99.99) of availability and require us to quickly drain any backlogs arising from sudden traffic spikes. At Walmart scale, we have a diverse set of Kafka consumer applications written in multiple languages. This diversity combined with our reliability requirements require consumer applications to adopt best practices to ensure high availability SLOs. High consumer lag due to Kafka consumer rebalancing is the most common challenge in operationalizing Kafka consumers at scale. In this article we highlight how Apache Kafka messages are reliably processed at a scale of trillions of messages per day with low cost and elasticity.

Challenges

Consumer rebalancing

A frequent problem encountered in production deployments of Kafka had to do with consumer rebalancing. Kafka rebalancing is the process by which Kafka redistributes partitions across consumers to ensure that each consumer is processing a roughly equal number of partitions. This ensures that data processing is distributed evenly across consumers and that each consumer is processing data as efficiently as possible. Kafka applications run either on containers or on VMs (a.k.a. Virtual Machines). For this article’s purposes, we focus on containers as that is prevalent in industry today. Kafka consumer applications built as container images run on WCNP (Walmart Cloud Native Platform) — an enterprise-grade, multi-cloud, container orchestration framework built on top of Kubernetes. Consumer rebalancing can thus be triggered by multiple causes, including:

A consumer pod entering a consumer group: This can be caused by K8s deployments or rolling-restarts or automatic/manual scale-outs.

The Kafka broker believing that a consumer has failed (e.g., if the broker has not received a heartbeat from a consumer within session.timeout.ms ): This will be triggered if the JVM exits or has a long stop-the-world garbage collection pause

The Kafka broker believing a consumer is stuck (e.g., if the consumer takes longer than max.poll.interval.ms to poll for the next batch of records to consume): This will be triggered if processing of the previously polled records exceeds this interval

While consumer rebalancing achieves resiliency in the face of both planned maintenance (e.g., code releases), standard operational practices (e.g., manually changing min pods / max pods settings), and automatic self-healing (e.g., pod crashes, autoscaling), it negatively impacts latency. Given the near real-time nature of commerce today, many Kafka use-cases have tight delivery SLAs — these applications suffered from constant lag alarms due to frequent and unpredictable rebalances in production.

There is no clean way to configure consumers to avoid rebalancing in Kafka today. Although the community provides static consumer membership and co-operative incremental rebalancing, these approaches come with their own challenges.

Poison pill

Head-of-line (HOL) blocking is a performance-limiting phenomenon that can occur in networking and messaging systems. It happens if a Kafka consumer encounters a message that will never successfully be processed. If message processing results in an uncaught exception thrown to the Kafka consumer thread, the consumer will re-consume the same message batch on the next poll of the broker — predictably, the same batch containing the “poison pill” message will result in the same exception. This loop will continue indefinitely until a code fix is deployed to the Kafka consumer application skipping the problematic message or correctly processing it or the problematic message is skipped by changing consumer offset. This poison-pill problem is yet another problem associated with in-order processing of partitioned data streams. Apache Kafka does not handle poison pill messages automatically.

Cost

There is strong coupling between the partitions in a topic and the consumer threads that read from them. The maximum number of consumers of a topic cannot exceed the number of partitions in that topic. If consumers are unable to keep up (i.e., maintain consistently low consumer lag) with topic flow, adding more consumers will only help until all partitions are assigned to a dedicated consumer thread. At this point, the number of partitions will need to be increased to increase the max number of consumers. While this might sound like a fine idea, there are general rules on the numbers of partitions you can add to a broker before needing to vertically scale the broker nodes up to the next biggest size (4000 partitions / broker)). As you can see, a problem with increasing consumer lag results in increasing partitions and potentially also scaling to larger brokers, even though the broker itself may have ample physical resources (e.g., memory, CPU, and storage). This strong coupling between partitions and consumers has long been the bane of many engineers who seek to maintain low latency in the face of increasing traffic in Kafka.

Kafka partition scalability

When there are thousands of pipelines, increasing the number of partitions becomes operationally onerous as it requires coordination among producers, consumers, and platform teams and imposes a small window of downtime. Sudden traffic spikes and large backlog draining both require increases in partitions and consumer pods.

Solution

To remedy some of the challenges above (e.g., the Kafka Consumer Rebalancing), the Kafka community has proposed the following Kafka Improvement Proposal: KIP-932: Queues for Kafka.

The Messaging Proxy Service (MPS) is a different path that is available. MPS decouples Kafka consumption from the constraint of partitions by proxying messages over HTTP to REST endpoints behind which consumers now wait. Via the MPS approach, Kafka consumption no longer suffers from rebalancing, while also allowing for greater throughput with a lower number of partitions.

An added benefit of the MPS approach is that application teams no longer must use Kafka consumer clients. This frees any Kafka team from having to chase application teams to upgrade Kafka client libraries.

Design

The MPS Kafka consumer consists of two independent thread groups: the Kafka message_reader thread (i.e., a group of 1 thread) and message_processing_writer threads. These thread groups are separated by a standard buffering pattern (pendingQueue). The reader thread writes to a bounded buffer (during the poll) and writer threads read from this buffer.

A bounded buffer also provides control on the speed of reader and writer threads. The message_reader thread will pause the consumer when the pendingQueue reaches a max buffer size.

This separation of reader and writer threads makes the reader thread incredibly lightweight and does not trigger a rebalance operation by exceeding max.poll.interval.ms. Now, the writer threads can take the time needed to process messages. The following diagram provides a pictorial view of the components and design.

Pictorial view of the components and design.

Sequence diagram models the interaction between the components as a sequence of calls.

The architecture above is composed of the following key components:

Reader Thread

The reader thread’s job is to make progress through the inbound topics, applying back-pressure when the PendingQueue is full.

Order Iterator

The order-iterator guarantees that keyed messages are processed in order. It iterates through all messages in pendingQueue and leaves the messages (i.e., temporarily skips) if there is already a message with the same key in flight. Skipped messages will be processed in subsequent poll calls once earlier messages with the same key are processed. By ensuring that no more than 1 message per key is in flight, MPS guarantees in-order delivery by key.

Writer Thread

The writer thread is part of a pool that provides greater throughput via parallelism. It’s job is to reliably write data to REST endpoints and DLQ’ing messages if either retries are exhausted or non retry-able HTTP response codes are received.

Dead Letter Queue (DLQ)

A DLQ topic can be created in every Kafka cluster. The message_processing_writer thread initially retries messages a fixed number of times with exponential back off. If this fails, the message is put in the DLQ topic. Applications can handle these messages later or discard them. Messages can be placed in this queue when the consumer service has an outage (e.g., timeouts) or if the consumer service encounters a poison pill (e.g., 500 HTTP Response).

Consumer Service

Consumer Service is stateless REST service for applications to process messages. This service contains business logic that was part of the processing originally available in the Kafka consumer application. With this new model, Kafka consumption (MPS) can be separated from message processing (Consumer Service). Below, you will find the REST API spec that must be implemented by any Consumer Service:

Kafka Offset Commit Thread

Kafka offset committing is implemented as a separate thread (i.e., the offset_commit thread). This thread wakes up at regular intervals (e.g., 1 minute) and commits the latest contiguous offsets which are successfully processed by writer threads.

In the picture above, the offset_commit thread commits offsets 124 and 150 for partitions 0 and 1, respectively

API



Implementation Details

MPS was implemented as a sink connector on Kafka connect. The Kafka Connect framework is well suited for the multiple reasons:

  • Multi-tenancy: Multiple connectors can be deployed on a single Kafka Connect cluster
  • DLQ handling: Kafka Connect already provides a basic framework for DLQ processing
  • Commit flow: Kafka Connect provides convenience methods for commits

In-built NFRs (Non-Functional Requirements): Kafka Connect provides many non-functional features (e.g., scalability, reliability)

Conclusion

MPS has eliminated rebalances due to slowness in downstream systems as it guarantees reader thread will put all messages in poll list in pendingQueue within allocated time of max.poll.interval.ms 5 minutes. The only rebalances we see are due to Kubernetes POD restarts and exceedingly rare network slowness between Kafka cluster and MPS. But with small consumer groups, the duration of these cycles is negligible and do not exceed processing SLAs (Service Level Agreements). MPS service and Kafka cluster should be hosted in the same cloud and region to reduce network related issues between them.

Cooperative handling of poison pills with applications detecting them and notifying MPS through the return codes 600 & 700 works as planned.

The cost benefits of this solution are realized in two areas. First, stateless consumer services can scale quickly in the Kubernetes environment and do not have to be scaled upfront for the holidays or any campaign events. Secondly, Kafka cluster sizes are no longer dependent on the partition sizes, they can be truly scaled for the throughput with about 5–10 MB per partition.

Huge improvements have been seen in rebalance related site issues and operational requests in Kafka pipelines due to yearly scaling of Kafka clusters for the holidays.

Sudden spikes in the traffic do not need to scale Kafka partitions anymore as stateless consumer services are easily auto scaled in the Kubernetes environment to handle message bursts.

Acknowledgements

This work would not be successful without the tireless aid of many people, some of whom are listed here:

(Aditya Athalye, Anuj Garg, Chandraprabha Rajput, Dilip Jaiswar, Gurpinder Singh, Hemant Tamhankar, Kamlesh Sangani, Malavika Gaddam, Mayakumar Vembunarayanan, Peter Newcomb, Raghu Baddam, Rohit Chatter, Sandip Mohod, Srikanth Bhattiprolu, Sriram Uppuluri, Thiruvalluvan M. G.)

Control web page caching, across all browsers?

Mike's Notes

I must prevent the browser from caching the HTML page and CSS file while writing and testing. Using headers is one way to avoid a web page's caching.

Preventing CSS caching requires a different technique

Resources

References

  • Reference

Repository

  • Home > Ajabbi Research > Library >
  • Home > Handbook > 

Last Updated

17/05/2025

Article

By: Mike Peters
On a Sandy Beach: 16/06/2024

Mike is the inventor and architect of Pipi and the founder of Ajabbi.

Options

  • Using HTML
  • Server
  • .htaccess
  • CSS

HTML Code

<meta http-equiv="Cache-Control" content="no-cache, no-store, must-revalidate">
<meta http-equiv="Pragma" content="no-cache">
<meta http-equiv="Expires" content="0">

- Stackoverflow

Notes

According to the tests described in the Stackoverflow post below, this works with these browsers.

  • Chrome 28
  • Firefox 23
  • IE8
  • Safari 5.1.7
  • Opera 12.15

.htaccess Code 1

".htaccess files allow web publishers to use commands normally only found in configuration files. They affect the content of the directory they’re in and their subdirectories. Talk to your server administrator to find out if they’re enabled.

.### activate mod_expires
ExpiresActive On
### Expire .gif's 1 month from when they're accessed
ExpiresByType image/gif A2592000
### Expire everything else 1 day from when it's last modified
### (this uses the Alternative syntax)
ExpiresDefault "modification plus 1 day"
### Apply a Cache-Control header to index.html
<Files index.html>
Header append Cache-Control "public, must-revalidate"
</Files>

Note that mod_expires automatically calculates and inserts a Cache-Control:max-age header as appropriate." - Apache Module mod_headers

.htaccess Code 2

<filesMatch "\.(html|htm|js|css)$">
FileETag None
<ifModule mod_headers.c>
Header unset ETag
Header set Cache-Control "max-age=0, no-cache, no-store, must-revalidate"
Header set Pragma "no-cache"
Header set Expires "Wed, 11 Jan 1984 05:00:00 GMT"
</ifModule>
</filesMatch>

- Stackoverflow

CSS

"You can append a random query parameter to the stylesheet url (for example via javascript or server side code). It will not change the css file that is being loaded, but it will prevent caching, because the browser detects a different url and will not load the cached stylesheet." - Stackoverflow

Code

<link rel="stylesheet" type="text/css" href="http://mysite/style.css?id=1234">

Breadcrumb Navigation

Mike's Notes

My job today was sorting out the default breadcrumb component for the Ajabbi Design System. Users with an account will be able to override this CSS.

Resources

References

  • Reference

Repository

  • Home > Ajabbi Research > Library >
  • Home > Handbook > 

Last Updated

17/06/2025

Article

By: Mike Peters
On a Sandy Beach: 15/06/2024

Mike is the inventor and architect of Pipi and the founder of Ajabbi.

"A breadcrumb navigation provides links back to each previous page the user navigated through, and shows the user's current location in a website." - w3Schools

I like something as simple as the one below.

Home > Pictures > Summer 15 

Here are examples of code from

  • w3schools
  • MDN
  • WAI-ARIA patterns
  • Ajabbi Design System.

From w3Schools

Example

Home > Pictures > Summer 15

Code

<ul class="breadcrumb">
  <li><a href="#">Home</a></li>
  <li><a href="#">Pictures</a></li>
  <li><a href="#">Summer 15</a></li>
  <li>Italy</li>
</ul>

CSS

/* Style the list */
ul.breadcrumb {
  padding: 10px 16px;
  list-style: none;
  background-color: #eee;
}

/* Display list items side by side */
ul.breadcrumb li {
  display: inline;
  font-size: 18px;
}

/* Add a slash symbol (/) before/behind each list item */
ul.breadcrumb li+li:before {
  padding: 8px;
  color: black;
  content: "/\00a0";
}

/* Add a color to all links inside the list */
ul.breadcrumb li a {
  color: #0275d8;
  text-decoration: none;
}

/* Add a color on mouse-over */
ul.breadcrumb li a:hover {
  color: #01447e;
  text-decoration: underline;
}

From WAI-ARIA Patterns

Example

WAI-ARIA Authoring Practices Guide (APG) > Patterns > Breadcrumb Pattern > Breadcrumb Example

Code

<nav aria-label="Breadcrumb" class="breadcrumb">
  <ol>
    <li>
      <a href="../../../../">
        WAI-ARIA Authoring Practices Guide (APG)
      </a>
    </li>
    <li>
      <a href="../../../">
        Patterns
      </a>
    </li>
    <li>
      <a href="../../">
        Breadcrumb Pattern
      </a>
    </li>
    <li>
      <a href="#" aria-current="page">
        Breadcrumb Example
      </a>
    </li>
  </ol>
</nav>

CSS

nav.breadcrumb {
  padding: 0.8em 1em;
  border: 1px solid hsl(0deg 0% 90%);
  border-radius: 4px;
  background: hsl(300deg 14% 97%);
}

nav.breadcrumb ol {
  margin: 0;
  padding-left: 0;
  list-style: none;
}

nav.breadcrumb li {
  display: inline;
}

nav.breadcrumb li + li::before {
  display: inline-block;
  margin: 0 0.25em;
  transform: rotate(15deg);
  border-right: 0.1em solid currentcolor;
  height: 0.8em;
  content: "";
}

nav.breadcrumb [aria-current="page"] {
  color: #000;
  font-weight: 700;
  text-decoration: none;
}

From MDN

Example

Home > Category > Sub Category > Type > Product

Code

<nav aria-label="Breadcrumb" class="breadcrumb">
  <ul>
    <li><a href="#">Home</a></li>
    <li><a href="#">Category</a></li>
    <li><a href="#">Sub Category</a></li>
    <li><a href="#">Type</a></li>
    <li><span aria-current="page">Product</span></li>
  </ul>
</nav>

CSS

.breadcrumb {
  padding: 0 .5rem;
}

.breadcrumb ul {
  display: flex;
  flex-wrap: wrap;
  list-style: none;
  margin: 0;
  padding: 0;
}

.breadcrumb li:not(:last-child)::after {
  display: inline-block;
  margin: 0 .25rem;
  content: "→";
}

From Ajabbi Design System

Example

Home > Design System > Components > Breadcrumb

Code

<nav aria-label="Breadcrumb" class="breadcrumb">
<ol>
  <li><a href="../../index.html">Home</a></li>
  <li><a href="../index.html">Design System</a></li>
  <li><a href="index.html">Components</a></li>
  <li><a href="#" aria-current="page">Breadcrumb</a></li>
</ol>
</nav>

CSS

nav.breadcrumb {
  padding: 0.8em 1em;
  border: 1px solid hsl(0deg 0% 90%);
  background: hsl(300deg 14% 97%);
}

nav.breadcrumb ol {
  margin: 0;
  padding-left: 0;
  list-style: none;
}

nav.breadcrumb li {
  display: inline;
}

nav.breadcrumb li + li::before {
  display: inline-block;
  margin: 0 0.25em;
  height: 0.8em;
  content: ">";
}

nav.breadcrumb [aria-current="page"] {
  color: #000;
  font-weight: 700;
  text-decoration: none;
}

Dynamic Web Apps without JavaScript - HTMX Showcase at DjangoCon and Devoxx

Mike's Notes

Discovering this presentation at QCon solved many problems and simplified the building of the Pipi UI.

Resources

References

  • Architectural Styles and the Design of Network-based Software Architectures by Roy Fielding

Repository

  • Home > Ajabbi Research > Library >
  • Home > Handbook > 

Last Updated

17/05/2025

Dynamic Web Apps without JavaScript - HTMX Showcase at DjangoCon and Devoxx

By: Bruno Couriol
InfQ.com: 21/10/2022

DjangoCon and Devoxx Belgium recently reported examples of interactive web applications developed without JavaScript developers. The showcased htmx HTML-first framework seems to target those applications that mainly propose a friendly interface to CRUD operations over remote resources. In one case, the team was able to remove the JavaScript developer.

At DjangoCon 2022, David Guillot reported reimplementing his company’s SaaS product with HTML-first framework htmx in two months with the following results:

Guillot gladly mentioned that 15,000 lines of JavaScript code disappeared from the codebase; performance improved (as measured by time to interactive and memory usage); the only JavaScript developer in the team left and back-end developers turned to full stack developers.

The htmx team however warns that such spectacular results were achieved because this particular SaaS application was a good fit for htmx’s HTML-first approach:

These are eye-popping numbers, and they reflect the fact that the Contexte application is extremely amenable to hypermedia: it is a content-focused application that shows lots of text and images. We would not expect every web application to see these sorts of numbers.

However, we would expect many applications to see dramatic improvements by adopting the hypermedia/htmx approach, at least for part of their system.

At Devoxx Belgium 2022, Wim Deblauwe showcased the kind of interactivity that htmx can implement without any JavaScript: search-as-you-type input field, update of the user interface as some remote resource is affected by CRUD operations, regularly refresh the user interface with server-sent data, and more.

The htmx team considers an application a good fit for the framework if the UI is mostly text and images; the UI mostly interfaces CRUD operations; and HTML updates mostly take place within well-defined blocks. Conversely, applications with many, dynamic interdependencies, that require offline functionality, or update state extremely frequently would not be a good first for htmx’s hypermedia approach.

In an htmx application, the server returns pages or fragments of pages.

<button hx-post="/clicked"

    hx-trigger="click"

    hx-target="#parent-div"

    hx-swap="outerHTML">

    Click Me!

</button>

The previous HTML excerpt encodes that when a user clicks on the button, htmx issues an HTTP POST request to the /clicked endpoint. Htmx uses the content from the posterior response to replace the element with the id parent-div in the DOM. With htmx, any element (i.e., not just anchors and forms), any event can trigger an HTTP request. The HTML response from the server only updates the relevant part of the UI. For the full overview of htmx capabilities, developers may refer to the documentation.

Interestingly, htmx is often showcased by back-end developers who belong to non-JavaScript ecosystems (e.g., Python/Django/Flask, PHP/Laravel, Ruby/Ruby on Rails). As Guillot mentioned, with htmx, back-end developers extend their scope to the entire stack without having to learn JavaScript, npm, Webpack, React, CSS-in-JS, and many more. Matt Layman, in his You don’t need JavaScript talk summarizes:

"It’s just this constant churn in the [JavaScript] ecosystem and adding a lot of complexity onto a flow when you’re trying to deliver a web application. You want to just get an experience out there that actually works for people. But then you end up fighting with [the toolchain].

At a certain amount of scale, JavaScript can be a fantastic thing to build into your applications. But for an average person or a small team, it’s a ton of extra complexity so my recommendation is: just don’t. We have other options."

htmx is an open-source project under the BSD-2-clause license.

htmx claims to provide AJAX, CSS Transitions, WebSockets, and Server-Sent Events directly in HTML, using attributes, so developers can build user interfaces with the simplicity and power of hypertext.

HTMX

Let’s look at the first feature of htmx: the ability of any web page element to issue HTTP requests. This is the core functionality provided by htmx, and it consists of five attributes that can be used to issue the five different developer-facing types of HTTP requests:

hx-get

Issues an HTTP GET request.

hx-post

Issues an HTTP POST request.

hx-put

Issues an HTTP PUT request.

hx-patch

Issues an HTTP PATCH request.

hx-delete

Issues an HTTP DELETE request.

hx-target

Relative Positional Expressions in Htmx.
  • next - Scan forward in the DOM for the next matching element, e.g., next .error
  • previousScan backwards in the DOM for the closest previous matching element, e.g., previous .alert
  • closest - Scan the parents of this element for the matching element, e.g., the closest table.
  • find - Scan the children of this element for matching element, e.g., find the span.
  • this - the current element is the target (default)

hx-swap

The hx-swap attribute supports the following values:

  • innerHTML - The default, replace the inner html of the target element.
  • outerHTML - Replace the entire target element with the response.
  • beforebegin - Insert the response before the target element.
  • afterbegin - Insert the response before the first child of the target element.
  • beforeend - Insert the response after the last child of the target element.
  • afterend - Insert the response after the target element.
  • delete - Deletes the target element regardless of the response.
  • none - No swap will be performed.
  • settle -Like swap, this allows you to apply a specific delay between when the content has been swapped into the DOM and when its attributes are “settled”, that is, updated from their old values (if any) to their new values. This can give you fine-grained control over CSS transitions.
  • show - Allows you to specify an element that should be shown — that is, scrolled into the viewport of the browser if necessary — when a request is completed.
  • scroll - Allows you to specify a scrollable element (that is, an element with scrollbars), that should be scrolled to the top or bottom when a request is completed.
  • focus-scroll - Allows you to specify that htmx should scroll to the focused element when a request completes. The default for this modifier is “false.”

hx-include


hx-vals


hx-push-url

“Pushes” the request URL (or some other value) into the navigation bar.

hx-location

Causes a client-side redirection to a new location

hx-preserve

Preserves a bit of the DOM between requests; the original content will be kept, regardless of what is returned.

hx-sync

Synchronized requests between two or more elements.

hx-disable

Disables htmx behavior on this element and any children. We will come back to this when we discuss the topic of security.

hx-boost


hx-confirm


hx-indicator

Let the user know that a search is in progress.

HTTP Request

When placed on an element, each attribute tells the htmx library: “When a user clicks (or whatever) this element, issue an HTTP request of the specified type.”

HX-Boosted

This will be the string “true” if the request is made via an element using hx-boost.

HX-Current-URL

This will be the browser's current URL.

HX-History-Restore-Request

This will be the string “true” if the request is for history restoration after a miss in the local history cache.

HX-Prompt

This will contain the user response to an hx-prompt.

HX-Request

This value is always “true” for htmx-based requests.

HX-Target

This value will be the id of the target element if it exists.

HX-Trigger-Name

If it exists, this value will be the name of the triggered element.

HX-Trigger

If it exists, this value will be the ID of the triggered element.
once. The given event will only trigger a request once.
  • delay - Allows you to specify a delay to wait before a request is issued. If the event occurs again, the first event is discarded and the timer resets. This allows you to “debounce” requests.
  • changed - Allows you to specify that a request should only be issued when the value property of the given element has changed.
  • throttle - Allows you to throttle events, only issuing them once every certain interval. This is different than delay in that the first event will trigger immediately, but any following events will not trigger until the throttle time period has elapsed.
  • from - A CSS selector that allows you to pick another element to listen for events on. We will see an example of this used later in the chapter.
  • target - A CSS selector that allows you to filter events to only those that occur directly on a given element. In the DOM, events “bubble” to their parent elements, so a click event on a button will also trigger a click event on a parent div, all the way up to the body element. Sometimes you want to specify an event directly on a given element, and this attribute allows you to do that.
  • consume - If this option is set to true, the triggering event will be cancelled and not propagate to parent elements.
  • queue - This option allows you to specify how events are queued in htmx. By default, when htmx receives a triggering event, it will issue a request and start an event queue. If the request is still in flight when another event is received, it will queue the event and, when the request finishes, trigger a new request. By default, it only keeps the last event it receives, but you can modify that behavior using this option: for example, you can set it to none and ignore all triggering events that occur during a request.

Lindy Effect

Mike's Notes

This is a curious thing.

Resources

References

  • Reference

Repository

  • Home > Ajabbi Research > Library >
  • Home > Handbook > 

Last Updated

17/05/2025

Lindy Effect

By: 
Wikipedia: 2024

"The Lindy effect (also known as Lindy's Law) is a theorized phenomenon by which the future life expectancy of some non-perishable things, like a technology or an idea, is proportional to their current age. Thus, the Lindy effect proposes the longer a period something has survived to exist or be used in the present, the longer its remaining life expectancy. Longevity implies a resistance to change, obsolescence, or competition, and greater odds of continued existence into the future.[2] Where the Lindy effect applies, mortality rate decreases with time. Mathematically, the Lindy effect corresponds to lifetimes following a Pareto probability distribution.

The concept is named after Lindy's delicatessen in New York City, where the concept was informally theorized by comedians. The Lindy effect has subsequently been theorized by mathematicians and statisticians. Nassim Nicholas Taleb has expressed the Lindy effect in terms of "distance from an absorbing barrier".

The Lindy effect applies to "non-perishable" items, those that do not have an "unavoidable expiration date". For example, human beings are perishable: the life expectancy at birth in developed countries is about 80 years. So the Lindy effect does not apply to individual human lifespan: all else being equal, it is less likely for a 10-year-old human to die within the next year than for a 100-year-old, while the Lindy effect would predict the opposite. ..." - Wikipedia