Skip to main content

Sites and Workspaces

Sites are the fundamental organizational unit in Sakai. A site is a workspace that contains pages, tools, and users with specific roles and permissions.

What is a Site?

A site is a workspace that:
  • Contains pages (tabs in the navigation)
  • Has tools placed on pages
  • Has users with specific roles
  • Defines permissions for what users can do
  • Can have groups for organizing subsets of users
In Sakai terminology, “site” and “workspace” are often used interchangeably. A site is essentially a container for organizing tools, users, and content.

Site Types

Sakai supports different types of sites:

Course Sites

Academic course workspaces with roster integration

Project Sites

Collaboration spaces for projects or groups

My Workspace

Personal workspace for each user

Site Interface

The Site interface represents a Sakai site:
package org.sakaiproject.site.api;

/**
 * Site is the object that knows the information, tools and 
 * layouts for a Sakai Site.
 */
public interface Site extends Edit, Comparable, Serializable, AuthzGroup {
    
    // Property names
    public static final String PROP_SITE_CONTACT_EMAIL = "contact-email";
    public static final String PROP_SITE_CONTACT_NAME = "contact-name";
    public static final String PROP_SITE_TERM = "term";
    public static final String PROP_SITE_TERM_EID = "term_eid";
    public static final String PROP_SITE_LANGUAGE = "locale_string";
    
    /**
     * @return the user who created this.
     */
    User getCreatedBy();
    
    /**
     * @return the user who last modified this.
     */
    User getModifiedBy();
}
Reference: kernel/api/src/main/java/org/sakaiproject/site/api/Site.java:35-100

Site Hierarchy

Sites have a hierarchical structure:

Pages

Pages are the tabs that appear in a site’s navigation. Each page can contain one or more tools.
// Get site pages
List<SitePage> pages = site.getPages();

for (SitePage page : pages) {
    // Get page properties
    String pageId = page.getId();
    String pageTitle = page.getTitle();
    int position = page.getPosition();
    
    // Get tools on this page
    List<ToolConfiguration> tools = page.getTools();
    
    for (ToolConfiguration tool : tools) {
        String toolId = tool.getToolId();
        String toolTitle = tool.getTitle();
        
        // Get tool configuration
        Properties config = tool.getConfig();
    }
}
Pages are ordered. Use getOrderedPages() to get pages in their display order, or page.getPosition() to get a specific page’s position.

Tool Placements

A tool placement (or tool configuration) is an instance of a tool on a page. The same tool can be placed multiple times with different configurations.
// Get a specific tool placement
ToolConfiguration toolConfig = page.getTool(placementId);

// Tool placement properties
String placementId = toolConfig.getId();
String toolId = toolConfig.getToolId();  // e.g., "sakai.assignment.grades"
String title = toolConfig.getTitle();
String layoutHints = toolConfig.getLayoutHints();

// Get placement configuration
Properties config = toolConfig.getConfig();
String customProperty = config.getProperty("custom.setting");

// Get the site context
String siteId = toolConfig.getContext();

Tool Configuration Properties

Tool placements can have custom configuration:
// Set tool configuration
Properties config = toolConfig.getPlacementConfig();
config.setProperty("display.users", "true");
config.setProperty("max.items", "20");

Groups

Groups organize subsets of users within a site. Groups can have their own permissions and can be used to restrict access to tools or resources.
// Get site groups
Collection<Group> groups = site.getGroups();

for (Group group : groups) {
    String groupId = group.getId();
    String groupTitle = group.getTitle();
    String groupDescription = group.getDescription();
    
    // Get group members
    Set<Member> members = group.getMembers();
    
    // Get group properties
    ResourceProperties props = group.getProperties();
}

// Get a specific group
Group group = site.getGroup(groupId);

// Create a new group
Group newGroup = site.addGroup();
newGroup.setTitle("Study Group A");
newGroup.setDescription("Monday study session");
Groups are particularly useful for:
  • Breaking a large class into sections
  • Creating project teams
  • Organizing discussion or assignment groups
  • Restricting access to specific resources

SiteService Operations

The SiteService provides comprehensive site management:
SiteService siteService = ComponentManager.get(SiteService.class);

// Get current site
String currentSiteId = ToolManager.getCurrentPlacement().getContext();
Site currentSite = siteService.getSite(currentSiteId);

// Check if site exists
boolean exists = siteService.siteExists(siteId);

// Get user's sites
List<Site> userSites = siteService.getUserSites();

// Get sites of a specific type
List<Site> courseSites = siteService.getSites(
    SelectionType.ANY,     // selection type
    "course",              // site type
    null,                  // search term
    null,                  // properties
    SortType.TITLE_ASC,    // sort order
    null                   // paging
);

Site Events

SiteService posts events for important operations:
EventDescription
site.visitUser visits a site
site.visit.unpUser visits an unpublished site
site.addSite is created
site.add.courseCourse site is created
site.add.projectProject site is created
site.updSite is updated
site.delSite is deleted
site.del.softSite is soft-deleted
Reference: kernel/api/src/main/java/org/sakaiproject/site/api/SiteService.java:67-100

Authorization in Sites

Sites implement the AuthzGroup interface, which means they define:
  • Roles: Named sets of permissions (e.g., “Instructor”, “Student”)
  • Users: Members with assigned roles
  • Permissions: What each role can do
// Site implements AuthzGroup
AuthzGroup siteRealm = site;

// Get user's role in site
Role userRole = siteRealm.getUserRole(userId);

// Check if user has permission
boolean canEdit = siteRealm.isAllowed(userId, "site.upd");

// Get all members
Set<Member> members = siteRealm.getMembers();

// Get users with a specific role
Set<Member> instructors = siteRealm.getUsersHasRole("Instructor");
Always use AuthzGroupService or the site’s authorization methods to check permissions. Never implement your own authorization logic.

Site Properties

Sites can have custom properties stored as name-value pairs:
// Get site properties
ResourceProperties props = site.getProperties();

// Get standard properties
String contactName = props.getProperty(Site.PROP_SITE_CONTACT_NAME);
String contactEmail = props.getProperty(Site.PROP_SITE_CONTACT_EMAIL);
String term = props.getProperty(Site.PROP_SITE_TERM);
String language = props.getProperty(Site.PROP_SITE_LANGUAGE);

// Get custom properties
String customProp = props.getProperty("institution.dept.code");

// Set properties (when editing)
ResourcePropertiesEdit propsEdit = site.getPropertiesEdit();
propsEdit.addProperty("custom.property", "value");

My Workspace

Each user has a personal workspace (My Workspace) with site ID in the format ~{userId}:
// Get current user's workspace
String userId = SessionManager.getCurrentSessionUserId();
String workspaceId = siteService.getUserSiteId(userId);
// workspaceId will be "~userid"

Site workspace = siteService.getSite(workspaceId);

// Alternative: Get user site directly
Site userSite = siteService.getSiteUserId(userId);

Best Practices

Before accessing a site, verify the user has permission:
// Check if user can access site
if (!siteService.allowAccessSite(siteId)) {
    throw new PermissionException(userId, "site.visit", siteId);
}

Site site = siteService.getSite(siteId);
Tools should always operate within the context of the current site:
// Get current site context
String siteId = ToolManager.getCurrentPlacement().getContext();
Site site = siteService.getSite(siteId);

// Don't hardcode site IDs
// Site site = siteService.getSite("abc123"); // WRONG!
Always save sites after making changes:
Site site = siteService.getSite(siteId);
site.setTitle("New Title");

// Don't forget to save!
siteService.save(site);
Leverage groups for organizing users and controlling access:
// Create groups for different sections
Group section1 = site.addGroup();
section1.setTitle("Section 1 - Morning");
section1.getProperties().addProperty("sections_category", "Lecture");

// Add users to group
section1.addMember(userId, "Student", true, false);

Common Site Operations

Get Current Site in a Tool

public class MyToolController {
    
    public String getCurrentSiteTitle() {
        try {
            // Get current placement's context (site ID)
            String siteId = ToolManager.getCurrentPlacement().getContext();
            
            // Get the site
            SiteService siteService = ComponentManager.get(SiteService.class);
            Site site = siteService.getSite(siteId);
            
            return site.getTitle();
        } catch (IdUnusedException e) {
            log.error("Site not found", e);
            return "Unknown Site";
        }
    }
}

Check if User is Instructor

public boolean isUserInstructor(String siteId, String userId) {
    try {
        Site site = siteService.getSite(siteId);
        Member member = site.getMember(userId);
        
        if (member == null) {
            return false;
        }
        
        Role role = member.getRole();
        return role != null && "Instructor".equals(role.getId());
    } catch (IdUnusedException e) {
        return false;
    }
}

Get All Tools in a Site

public List<String> getAllToolsInSite(String siteId) {
    List<String> toolIds = new ArrayList<>();
    
    try {
        Site site = siteService.getSite(siteId);
        
        for (SitePage page : site.getPages()) {
            for (ToolConfiguration tool : page.getTools()) {
                toolIds.add(tool.getToolId());
            }
        }
    } catch (IdUnusedException e) {
        log.error("Site not found: " + siteId, e);
    }
    
    return toolIds;
}

Next Steps

Architecture Overview

Understand the overall system architecture

Kernel Services

Learn about core kernel services

Tool Architecture

Build tools that integrate with sites

Build docs developers (and LLMs) love