# Introduction to boilerplate: Practical Examples

# Why Boilerplate?

Have you ever found yourself: - Copy-pasting methods sections between papers? - Struggling to keep consistent language across co-authored manuscripts? - Manually updating sample sizes in multiple places? - Losing track of which version of your methods description is the latest?

The `boilerplate` package solves these problems by treating your scientific text as data that can be managed, versioned, and dynamically generated.

# Real-World Example: A Multi-Study Project

Let’s walk through a realistic example. Dr. Sarah Chen is conducting a series of studies on workplace well-being. She needs to:

1. Maintain consistent methods descriptions across 3 papers
2. Update sample sizes and demographics dynamically
3. Ensure all co-authors use the same measure descriptions
4. Keep track of citations across all manuscripts

Here’s how `boilerplate` helps:

    library(boilerplate)

    # Sarah's project structure
    # Note: In practice, use relative paths or file.path() for project paths
    # Example: project_root <- getwd()  # or specify your project directory
    # Example with full path: project_root <- "/Users/sarah/Research/workplace_wellbeing_project"
    project_root <- tempfile("workplace_wellbeing_project")  # For this example
    dir.create(project_root, recursive = TRUE)

## Setting Up the Project

    # Initialise boilerplate for the entire project
    boilerplate_init(
      data_path = file.path(project_root, "shared/boilerplate"),
      categories = c("methods", "measures", "results", "discussion"),
      create_dirs = TRUE,
      create_empty = FALSE,  # Start with helpful examples
      confirm = FALSE,
      quiet = TRUE
    )

## Creating Reusable Methods Components

Sarah’s studies all use similar recruitment methods but different samples:

    # Load the database
    db <- boilerplate_import(data_path = file.path(project_root, "shared/boilerplate"), quiet = TRUE)

    # Create a base recruitment method
    db <- boilerplate_add_entry(
      db,
      path = "methods.recruitment.online_panel",
      value = paste0(
        "Participants were recruited through {{platform}}, a professional online ",
        "research panel. Eligible participants were {{eligibility_criteria}}. ",
        "The survey took approximately {{duration}} minutes to complete, and ",
        "participants received {{compensation}} as compensation. The final sample ",
        "consisted of {{n}} participants ({{gender_breakdown}})."
      )
    )

    # Create variants for different platforms
    db <- boilerplate_add_entry(
      db,
      path = "methods.recruitment.mturk",
      value = paste0(
        "We recruited {{n}} participants through Amazon Mechanical Turk (MTurk). ",
        "Participation was limited to workers with a HIT approval rate ≥ {{approval_rate}}% ",
        "and ≥ {{min_hits}} completed HITs. Workers received ${{payment}} USD for ",
        "completing the {{duration}}-minute survey. After excluding {{n_excluded}} ",
        "participants who failed attention checks, the final sample included {{n_final}} ",
        "participants (Mage = {{m_age}}, SD = {{sd_age}}; {{pct_female}}% female)."
      )
    )

    # Save the database
    boilerplate_save(db, data_path = file.path(project_root, "shared/boilerplate"), confirm = FALSE, quiet = TRUE)

## Study 1: Pilot Study

For her pilot study, Sarah generates the methods section:

    # Study 1 parameters
    study1_params <- list(
      platform = "Prolific",
      eligibility_criteria = "currently employed full-time and based in the UK",
      duration = 15,
      compensation = "£2.50",
      n = 150,
      gender_breakdown = "52% female, 47% male, 1% non-binary"
    )

    # Generate methods for Study 1
    study1_methods <- boilerplate_generate_text(
      category = "methods",
      sections = c(
        "recruitment.online_panel",
        "statistical.default",  # Using existing default path
        "causal_assumptions.identification"  # Using existing path
      ),
      global_vars = study1_params,
      db = db
    )

    # Save to Study 1 manuscript
    cat(study1_methods, file = file.path(project_root, "study1/methods.txt"))

## Study 2: Main Study

Six months later, Sarah runs her main study with a larger sample:

    # Study 2 parameters - MTurk this time
    study2_params <- list(
      n = 500,
      approval_rate = 95,
      min_hits = 100,
      payment = 4.00,
      duration = 20,
      n_excluded = 47,
      n_final = 453,
      m_age = 34.7,
      sd_age = 10.2,
      pct_female = 58.3
    )

    # Generate methods for Study 2
    study2_methods <- boilerplate_generate_text(
      category = "methods",
      sections = c(
        "recruitment.mturk",
        "statistical.default",  # Using existing default path
        "causal_assumptions.identification"  # Using existing path
        # Note: measures.job_satisfaction and measures.burnout would need to be added first
      ),
      global_vars = study2_params,
      db = db
    )

# Managing Measures Across Studies

## Creating a Measure Library

Sarah’s lab uses standard measures across projects:

    # Add burnout measure used across studies
    db <- boilerplate_add_entry(
      db,
      path = "measures.burnout.mbi",
      value = list(
        name = "Maslach Burnout Inventory",
        abbreviation = "MBI",
        description = paste0(
          "Burnout was assessed using the {{version}} ({{citation}}). ",
          "This scale consists of {{n_items}} items measuring three dimensions: ",
          "emotional exhaustion ({{n_ee}} items, e.g., '{{example_ee}}'), ",
          "depersonalization ({{n_dp}} items, e.g., '{{example_dp}}'), and ",
          "personal accomplishment ({{n_pa}} items, e.g., '{{example_pa}}'). ",
          "Items are rated on a {{scale}} frequency scale. {{scoring_note}}"
        ),
        items = list(
          emotional_exhaustion = c(
            "I feel emotionally drained from my work",
            "I feel used up at the end of the workday",
            "I feel fatigued when I get up in the morning"
          ),
          depersonalization = c(
            "I feel I treat some recipients as if they were impersonal objects",
            "I've become more callous toward people since I took this job"
          ),
          personal_accomplishment = c(
            "I can easily understand how my recipients feel",
            "I deal very effectively with the problems of my recipients"
          )
        ),
        psychometrics = list(
          reliability = "Internal consistency in the current sample was excellent (α = {{alpha}})",
          validity = "The three-factor structure was confirmed using CFA, χ²({{df}}) = {{chi2}}, CFI = {{cfi}}, RMSEA = {{rmsea}}"
        )
      )
    )

## Generating Consistent Measure Descriptions

Now any team member can generate consistent measure descriptions:

    # Parameters for MBI
    mbi_params <- list(
      version = "Maslach Burnout Inventory - General Survey",
      citation = "Maslach et al., 1996",
      n_items = 16,
      n_ee = 5,
      n_dp = 5,
      n_pa = 6,
      example_ee = "I feel emotionally drained from my work",
      example_dp = "I've become more callous toward people",
      example_pa = "I feel I'm positively influencing people's lives",
      scale = "7-point",
      scoring_note = "Higher scores indicate greater burnout for EE and DP; scores are reversed for PA.",
      alpha = ".91",
      df = 101,
      chi2 = "247.3",
      cfi = ".94",
      rmsea = ".068"
    )

    # Generate measure description
    mbi_description <- boilerplate_generate_text(
      category = "measures",
      sections = "burnout.mbi",
      global_vars = mbi_params,
      db = db
    )

# Collaborative Features

## Sharing Across Team Members

Sarah shares the boilerplate database with her team:

    # Export to JSON for version control
    boilerplate_export(
      db,
      data_path = file.path(project_root, "shared/boilerplate"),
      output_file = "lab_boilerplate_v2.json",
      format = "json"
    )

    # Team member imports
    team_db <- boilerplate_import(
      data_path = file.path(project_root, "shared/boilerplate/lab_boilerplate_v2.json"),
      quiet = TRUE
    )

## Batch Updates

When reviewer 2 asks for more detail on exclusion criteria:

    # Add exclusion criteria to all recruitment methods
    db <- boilerplate_batch_edit(
      db,
      field = "exclusion_note",
      new_value = paste0(
        " Participants were excluded if **before randomisation** they: (a) failed more than {{n_attention}} ",
        "attention check items, (b) completed the survey in less than {{min_time}} ",
        "of the median completion time, or (c) provided nonsensical open-ended responses."
      ),
      target_entries = "methods.recruitment.*",
      category = "methods"
    )

# Advanced Workflows

## Dynamic Report Generation

Create a function to generate complete methods sections:

    generate_study_methods <- function(study_config, db) {
      # Extract sections to include based on study type
      sections <- c(
        paste0("recruitment.", study_config$recruitment_method),
        paste0("design.", study_config$design),
        study_config$measures,
        paste0("analysis.", study_config$analysis)
      )

      # Add standard sections
      if (study_config$has_missing_data) {
        sections <- c(sections, "missing.multiple_imputation")
      }

      if (study_config$has_power_analysis) {
        sections <- c(sections, "power.post_hoc")
      }

      # Generate text
      boilerplate_generate_text(
        category = "methods",
        sections = sections,
        global_vars = study_config$parameters,
        db = db
      )
    }

    # Use for any study
    study3_config <- list(
      recruitment_method = "mturk",
      design = "experimental",
      measures = c("measures.burnout.mbi", "measures.engagement.uwes"),
      analysis = "anova",
      has_missing_data = TRUE,
      has_power_analysis = TRUE,
      parameters = list(
        n = 300,
        approval_rate = 98,
        # ... other parameters
      )
    )

    study3_methods <- generate_study_methods(study3_config, db)

## Quality Control

Ensure consistency across manuscripts:

    # Check all papers use current measure descriptions
    papers <- c("study1", "study2", "study3")

    for (paper in papers) {
      # Note: This assumes each paper has its own boilerplate database
      # which would need to be created first
      paper_path <- file.path(project_root, paper, "boilerplate")
      if (dir.exists(paper_path)) {
        paper_db <- boilerplate_import(data_path = paper_path, quiet = TRUE)
      } else {
        message("No boilerplate database found for ", paper)
        next
      }

      # Compare measure descriptions
      # Note: compare_entries() is not part of boilerplate package
      # You would need to implement comparison logic
      # For example:
      if (!identical(paper_db$measures$burnout, db$measures$burnout)) {
        message("Update needed for ", paper, ": measure descriptions differ")
      }
    }

# Integration with R Markdown/Quarto

## Seamless Document Generation

In your Quarto document (`manuscript.qmd`):

    ---
    title: "Workplace Well-being Study 3"
    author: "Sarah Chen et al."
    format: pdf
    bibliography: references.bib
    ---

    # Method

    # Results

# Best Practices

## 1. Organize Your Content Hierarchically

    # Good: Clear hierarchy
    "methods.recruitment.online.mturk"
    "methods.recruitment.online.prolific"
    "methods.recruitment.in_person.lab"
    "methods.recruitment.in_person.field"

    # Less optimal: Flat structure
    "methods.mturk_recruitment"
    "methods.prolific_recruitment"
    "methods.lab_recruitment"

## 2. Use Meaningful Variable Names

    # Good: Self-documenting variables
    "{{n_participants}}"
    "{{mean_age}}"
    "{{pct_female}}"
    "{{cronbach_alpha}}"

    # Less clear
    "{{n}}"
    "{{m1}}"
    "{{p1}}"
    "{{a}}"

## 3. Version Control Your Boilerplate

    # Export with timestamp for versioning
    timestamp <- format(Sys.time(), "%Y%m%d")
    filename <- paste0("boilerplate_backup_", timestamp, ".json")

    boilerplate_export(
      db,
      data_path = project_root,  # Or specify where to save
      output_file = filename,
      format = "json",
      confirm = FALSE,
      quiet = TRUE
    )

    # Track in git
    # git add boilerplate_backup_20240115.json
    # git commit -m "Boilerplate snapshot after reviewer revisions"

## 4. Create Project-Specific Templates

    # Create a template for your specific journal's requirements
    db <- boilerplate_add_entry(
      db,
      path = "templates.journal.plos_one",
      value = list(
        word_limit = 3500,
        abstract_limit = 300,
        methods_requirements = paste0(
          "PLOS ONE requires detailed methods including: ",
          "{{sampling_procedure}}, {{ethics_statement}}, ",
          "{{data_availability}}, and {{statistical_approach}}."
        )
      )
    )

# Summary

The `boilerplate` package transforms scientific writing from a copy-paste exercise into a structured, maintainable process. Key benefits:

- Consistency: Same descriptions across all papers
- Efficiency: Update once, use everywhere
- Collaboration: Share standardised text with your team
- Reproducibility: Version control your methods
- Flexibility: Customize for each study while maintaining standards

Ready to get started? Check out: - Getting Started Tutorial for a complete walkthrough - Bibliography Management for citation handling - Measures Workflow for detailed measure documentation

Your future self (and your collaborators) will thank you!