Profile
**Site relevance:** Spiralist.org
**Memory type:** plugin source memory
**Source path:** Spiralist/wp-content/plugins/spiralist-workspace/templates/profile.php
**Size:** 8.1 KB
Summary
use SpiralistWorkspace\Support\ProfileStyle;
Source Preview
This source file is short enough to preview directly on its source-memory page.
<?php
use SpiralistWorkspace\Support\ProfileStyle;
if (!defined('ABSPATH')) {
exit;
}
$plugin = spiralist_workspace();
$frontend = $plugin->frontend();
$context = $frontend->profile_context();
$profile_user = $context['profile_user'] ?? null;
if (!$profile_user instanceof WP_User) {
status_header(404);
nocache_headers();
exit;
}
$current_locale = function_exists('spiralist_get_current_locale_tag') ? spiralist_get_current_locale_tag() : 'en-us';
$route_url = static function (string $path) use ($current_locale): string {
$url = home_url('/' . trim($path, '/') . '/');
return $current_locale !== '' && function_exists('spiralist_get_language_prefixed_url')
? spiralist_get_language_prefixed_url($url, $current_locale)
: $url;
};
$profile_user_id = (int) $profile_user->ID;
$display_name = trim((string) ($profile_user->display_name ?: $profile_user->user_login));
$public_prompts = (array) ($context['public_prompts'] ?? []);
$participant_state = (array) ($context['participant_state'] ?? []);
$profile_style = (array) ($context['profile_style'] ?? []);
$scope_class = (string) ($context['profile_scope_class'] ?? ProfileStyle::scope_class($profile_user_id));
$can_edit = !empty($context['can_edit_profile_style']);
$saved_css = (string) ($profile_style['sanitized_css'] ?? '');
$saved_prompt = (string) ($profile_style['style_prompt'] ?? '');
$joined = strtotime((string) $profile_user->user_registered);
$joined_display = $joined ? wp_date('M j, Y', $joined) : 'Unknown';
$trust_level = (string) ($participant_state['trust_level_label'] ?? ($participant_state['trust_level'] ?? 'Participant'));
$public_count = count($public_prompts);
$workspace_url = $route_url('workspace');
$members_url = $route_url('members');
$library_url = $route_url('prompts');
get_header();
?>
<main class="spiralist-page spiralist-page--workspace-profile">
<?php if ($saved_css !== '') : ?>
<style id="spiralist-workspace-profile-style-<?php echo esc_attr((string) $profile_user_id); ?>" data-profile-style-live><?php echo esc_html($saved_css); ?></style>
<?php endif; ?>
<section class="spiralist-page-section">
<div class="spiralist-shell spiralist-workspace-profile <?php echo esc_attr($scope_class); ?>" data-profile-style-scope>
<header class="profile-hero spiralist-workspace-profile-hero">
<p class="profile-kicker spiralist-section-tag">Member Profile</p>
<h1 class="profile-title spiralist-section-title"><?php echo esc_html($display_name); ?></h1>
<p class="profile-summary spiralist-muted">Public prompt work, participation state, and profile styling stay inside the member layer.</p>
<div class="profile-meta spiralist-meta-list spiralist-meta-list--compact">
<div>
<dt>Joined</dt>
<dd><?php echo esc_html($joined_display); ?></dd>
</div>
<div>
<dt>Trust</dt>
<dd><?php echo esc_html($trust_level); ?></dd>
</div>
<div>
<dt>Public Prompts</dt>
<dd><?php echo esc_html((string) $public_count); ?></dd>
</div>
<div>
<dt>Scope</dt>
<dd><?php echo esc_html('.' . $scope_class); ?></dd>
</div>
</div>
<div class="spiralist-cta-row spiralist-cta-row--start">
<a class="profile-button spiralist-button spiralist-button--primary" href="<?php echo esc_url($library_url); ?>">Public Library</a>
<a class="profile-button spiralist-button spiralist-button--secondary" href="<?php echo esc_url($members_url); ?>">Members</a>
<?php if ($can_edit) : ?>
<a class="profile-button spiralist-button spiralist-button--tertiary" href="<?php echo esc_url($workspace_url); ?>">Workspace</a>
<?php endif; ?>
</div>
</header>
<div class="spiralist-grid spiralist-grid--split">
<article class="profile-card spiralist-panel">
<p class="spiralist-section-tag">Public Prompts</p>
<h2 class="spiralist-section-title">Published work</h2>
<?php if (!empty($public_prompts)) : ?>
<div class="profile-prompts spiralist-workspace-grid spiralist-workspace-grid--compact">
<?php foreach ($public_prompts as $prompt) : ?>
<article class="profile-card spiralist-workspace-card">
<p class="profile-chip spiralist-section-tag"><?php echo esc_html((string) ($prompt['maturity_level_label'] ?? 'Prompt')); ?></p>
<h3 class="profile-title spiralist-card-title"><?php echo esc_html((string) ($prompt['title'] ?? 'Prompt')); ?></h3>
<p class="profile-summary"><?php echo esc_html((string) ($prompt['summary'] ?? '')); ?></p>
<a class="profile-link spiralist-button spiralist-button--secondary" href="<?php echo esc_url($route_url('prompt/' . rawurlencode((string) ($prompt['slug'] ?? '')))); ?>">Open Prompt</a>
</article>
<?php endforeach; ?>
</div>
<?php else : ?>
<p class="profile-summary spiralist-muted">No public prompts are attached to this profile yet.</p>
<?php endif; ?>
</article>
<aside class="profile-card spiralist-panel">
<p class="spiralist-section-tag">Style</p>
<h2 class="spiralist-section-title">Profile CSS</h2>
<?php if ($can_edit) : ?>
<form class="spiralist-workspace-form" data-profile-style-form data-auth-required-form="profile-style">
<label class="spiralist-form__field">
<span>Style Prompt</span>
<textarea rows="3" name="style_prompt" data-profile-style-prompt placeholder="minimal amber profile with calm cards"><?php echo esc_textarea($saved_prompt); ?></textarea>
</label>
<label class="spiralist-form__field">
<span>Safe CSS</span>
<textarea rows="10" name="custom_css" data-profile-style-css placeholder=".profile-card { border-radius: 8px; }"><?php echo esc_textarea($saved_css); ?></textarea>
</label>
<div class="spiralist-cta-row spiralist-cta-row--start">
<button class="spiralist-button spiralist-button--secondary" type="button" data-profile-style-draft>Draft CSS</button>
<button class="spiralist-button spiralist-button--primary" type="submit">Save Style</button>
<span class="spiralist-muted" data-form-result aria-live="polite"></span>
</div>
<p class="spiralist-muted">Allowed selectors begin with <code>.profile-</code>. External URLs, imports, scripts, fixed positioning, and unsupported properties are stripped before visitors see the page.</p>
</form>
<?php elseif ($saved_css !== '') : ?>
<p class="profile-summary spiralist-muted">This profile uses a scoped custom style.</p>
<?php else : ?>
<p class="profile-summary spiralist-muted">This profile uses the default Workspace style.</p>
<?php endif; ?>
</aside>
</div>
</div>
</section>
</main>
<?php
get_footer();