// XXX: attributes (profile?)
$this->elementStart('head');
if (Event::handle('StartShowHeadElements', array($this))) {
- $this->showTitle();
+ if (Event::handle('StartShowHeadTitle', array($this))) {
+ $this->showTitle();
+ Event::handle('EndShowHeadTitle', array($this));
+ }
$this->showShortcutIcon();
$this->showStylesheets();
$this->showOpenSearch();
function showTitle()
{
$this->element('title', null,
+ // TRANS: Page title. %1$s is the title, %2$s is the site name.
sprintf(_("%1\$s - %2\$s"),
$this->title(),
common_config('site', 'name')));
function title()
{
+ // TRANS: Page title for a page without a title set.
return _("Untitled page");
}
if (Event::handle('StartShowStatusNetStyles', array($this)) &&
Event::handle('StartShowLaconicaStyles', array($this))) {
- $this->cssLink('css/display.css',null,'screen, projection, tv');
- $this->cssLink('css/print.css','base','print');
+ $this->primaryCssLink(null, 'screen, projection, tv, print');
Event::handle('EndShowStatusNetStyles', array($this));
Event::handle('EndShowLaconicaStyles', array($this));
}
Event::handle('EndShowDesign', array($this));
}
Event::handle('EndShowStyles', array($this));
+
+ if (common_config('custom_css', 'enabled')) {
+ $css = common_config('custom_css', 'css');
+ if (Event::handle('StartShowCustomCss', array($this, &$css))) {
+ if (trim($css) != '') {
+ $this->style($css);
+ }
+ Event::handle('EndShowCustomCss', array($this));
+ }
+ }
+ }
+ }
+
+ function primaryCssLink($mainTheme=null, $media=null)
+ {
+ // If the currently-selected theme has dependencies on other themes,
+ // we'll need to load their display.css files as well in order.
+ $theme = new Theme($mainTheme);
+ $baseThemes = $theme->getDeps();
+ foreach ($baseThemes as $baseTheme) {
+ $this->cssLink('css/display.css', $baseTheme, $media);
}
+ $this->cssLink('css/display.css', $mainTheme, $media);
}
/**
}
if (Event::handle('StartShowStatusNetScripts', array($this)) &&
Event::handle('StartShowLaconicaScripts', array($this))) {
- $this->script('xbImportNode.js');
$this->script('util.js');
- $this->script('geometa.js');
// Frame-busting code to avoid clickjacking attacks.
$this->inlineScript('if (window.top !== window.self) { window.top.location.href = window.self.location.href; }');
Event::handle('EndShowStatusNetScripts', array($this));
{
$user = common_current_user();
$this->elementStart('dl', array('id' => 'site_nav_global_primary'));
+ // TRANS: DT element for primary navigation menu. String is hidden in default CSS.
$this->element('dt', null, _('Primary site navigation'));
$this->elementStart('dd');
$this->elementStart('ul', array('class' => 'nav'));
if ($user) {
// TRANS: Tooltip for main menu option "Personal"
$tooltip = _m('TOOLTIP', 'Personal profile and friends timeline');
- // TRANS: Main menu option when logged in for access to personal profile and friends timeline
$this->menuItem(common_local_url('all', array('nickname' => $user->nickname)),
+ // TRANS: Main menu option when logged in for access to personal profile and friends timeline
_m('MENU', 'Personal'), $tooltip, false, 'nav_home');
// TRANS: Tooltip for main menu option "Account"
$tooltip = _m('TOOLTIP', 'Change your email, avatar, password, profile');
- // TRANS: Main menu option when logged in for access to user settings
$this->menuItem(common_local_url('profilesettings'),
+ // TRANS: Main menu option when logged in for access to user settings
_('Account'), $tooltip, false, 'nav_account');
// TRANS: Tooltip for main menu option "Services"
$tooltip = _m('TOOLTIP', 'Connect to services');
- // TRANS: Main menu option when logged in and connection are possible for access to options to connect to other services
$this->menuItem(common_local_url('oauthconnectionssettings'),
+ // TRANS: Main menu option when logged in and connection are possible for access to options to connect to other services
_('Connect'), $tooltip, false, 'nav_connect');
if ($user->hasRight(Right::CONFIGURESITE)) {
// TRANS: Tooltip for menu option "Admin"
$tooltip = _m('TOOLTIP', 'Change site configuration');
- // TRANS: Main menu option when logged in and site admin for access to site configuration
$this->menuItem(common_local_url('siteadminpanel'),
+ // TRANS: Main menu option when logged in and site admin for access to site configuration
_m('MENU', 'Admin'), $tooltip, false, 'nav_admin');
}
if (common_config('invite', 'enabled')) {
// TRANS: Tooltip for main menu option "Invite"
$tooltip = _m('TOOLTIP', 'Invite friends and colleagues to join you on %s');
- // TRANS: Main menu option when logged in and invitations are allowed for inviting new users
$this->menuItem(common_local_url('invite'),
+ // TRANS: Main menu option when logged in and invitations are allowed for inviting new users
_m('MENU', 'Invite'),
sprintf($tooltip,
common_config('site', 'name')),
}
// TRANS: Tooltip for main menu option "Logout"
$tooltip = _m('TOOLTIP', 'Logout from the site');
- // TRANS: Main menu option when logged in to log out the current user
$this->menuItem(common_local_url('logout'),
+ // TRANS: Main menu option when logged in to log out the current user
_m('MENU', 'Logout'), $tooltip, false, 'nav_logout');
}
else {
- if (!common_config('site', 'closed')) {
+ if (!common_config('site', 'closed') && !common_config('site', 'inviteonly')) {
// TRANS: Tooltip for main menu option "Register"
$tooltip = _m('TOOLTIP', 'Create an account');
- // TRANS: Main menu option when not logged in to register a new account
$this->menuItem(common_local_url('register'),
+ // TRANS: Main menu option when not logged in to register a new account
_m('MENU', 'Register'), $tooltip, false, 'nav_register');
}
// TRANS: Tooltip for main menu option "Login"
function showLocalNavBlock()
{
$this->elementStart('dl', array('id' => 'site_nav_local_views'));
+ // TRANS: DT element for local views block. String is hidden in default CSS.
$this->element('dt', null, _('Local views'));
$this->elementStart('dd');
$this->showLocalNav();
function showContentBlock()
{
$this->elementStart('div', array('id' => 'content'));
- $this->showPageTitle();
+ if (Event::handle('StartShowPageTitle', array($this))) {
+ $this->showPageTitle();
+ Event::handle('EndShowPageTitle', array($this));
+ }
$this->showPageNoticeBlock();
$this->elementStart('div', array('id' => 'content_inner'));
// show the actual content (forms, lists, whatever)
$this->elementStart('dl', array('id' => 'page_notice',
'class' => 'system_notice'));
+ // TRANS: DT element for page notice. String is hidden in default CSS.
$this->element('dt', null, _('Page notice'));
$this->elementStart('dd');
if (Event::handle('StartShowPageNotice', array($this))) {
function showSecondaryNav()
{
$this->elementStart('dl', array('id' => 'site_nav_global_secondary'));
+ // TRANS: DT element for secondary navigation menu. String is hidden in default CSS.
$this->element('dt', null, _('Secondary site navigation'));
$this->elementStart('dd', null);
$this->elementStart('ul', array('class' => 'nav'));
if (Event::handle('StartSecondaryNav', array($this))) {
$this->menuItem(common_local_url('doc', array('title' => 'help')),
+ // TRANS: Secondary navigation menu option leading to help on StatusNet.
_('Help'));
$this->menuItem(common_local_url('doc', array('title' => 'about')),
+ // TRANS: Secondary navigation menu option leading to text about StatusNet site.
_('About'));
$this->menuItem(common_local_url('doc', array('title' => 'faq')),
+ // TRANS: Secondary navigation menu option leading to Frequently Asked Questions.
_('FAQ'));
$bb = common_config('site', 'broughtby');
if (!empty($bb)) {
$this->menuItem(common_local_url('doc', array('title' => 'tos')),
+ // TRANS: Secondary navigation menu option leading to Terms of Service.
_('TOS'));
}
$this->menuItem(common_local_url('doc', array('title' => 'privacy')),
+ // TRANS: Secondary navigation menu option leading to privacy policy.
_('Privacy'));
$this->menuItem(common_local_url('doc', array('title' => 'source')),
+ // TRANS: Secondary navigation menu option.
_('Source'));
$this->menuItem(common_local_url('version'),
+ // TRANS: Secondary navigation menu option leading to version information on the StatusNet site.
_('Version'));
$this->menuItem(common_local_url('doc', array('title' => 'contact')),
+ // TRANS: Secondary navigation menu option leading to contact information on the StatusNet site.
_('Contact'));
$this->menuItem(common_local_url('doc', array('title' => 'badge')),
_('Badge'));
*/
function showStatusNetLicense()
{
+ // TRANS: DT element for StatusNet software license.
$this->element('dt', array('id' => 'site_statusnet_license'), _('StatusNet software license'));
$this->elementStart('dd', null);
if (common_config('site', 'broughtby')) {
- $instr = _('**%%site.name%%** is a microblogging service brought to you by [%%site.broughtby%%](%%site.broughtbyurl%%). ');
+ // TRANS: First sentence of the StatusNet site license. Used if 'broughtby' is set.
+ $instr = _('**%%site.name%%** is a microblogging service brought to you by [%%site.broughtby%%](%%site.broughtbyurl%%).');
} else {
- $instr = _('**%%site.name%%** is a microblogging service. ');
+ // TRANS: First sentence of the StatusNet site license. Used if 'broughtby' is not set.
+ $instr = _('**%%site.name%%** is a microblogging service.');
}
+ $instr .= ' ';
+ // TRANS: Second sentence of the StatusNet site license. Mentions the StatusNet source code license.
$instr .= sprintf(_('It runs the [StatusNet](http://status.net/) microblogging software, version %s, available under the [GNU Affero General Public License](http://www.fsf.org/licensing/licenses/agpl-3.0.html).'), STATUSNET_VERSION);
$output = common_markup_to_html($instr);
$this->raw($output);
function showContentLicense()
{
if (Event::handle('StartShowContentLicense', array($this))) {
+ // TRANS: DT element for StatusNet site content license.
$this->element('dt', array('id' => 'site_content_license'), _('Site content license'));
$this->elementStart('dd', array('id' => 'site_content_license_cc'));
switch (common_config('license', 'type')) {
case 'private':
+ // TRANS: Content license displayed when license is set to 'private'.
+ // TRANS: %1$s is the site name.
$this->element('p', null, sprintf(_('Content and data of %1$s are private and confidential.'),
common_config('site', 'name')));
// fall through
case 'allrightsreserved':
if (common_config('license', 'owner')) {
+ // TRANS: Content license displayed when license is set to 'allrightsreserved'.
+ // TRANS: %1$s is the copyright owner.
$this->element('p', null, sprintf(_('Content and data copyright by %1$s. All rights reserved.'),
common_config('license', 'owner')));
} else {
+ // TRANS: Content license displayed when license is set to 'allrightsreserved' and no owner is set.
$this->element('p', null, _('Content and data copyright by contributors. All rights reserved.'));
}
break;
'width' => '80',
'height' => '15'));
$this->text(' ');
- //TODO: This is dirty: i18n
- $this->text(_('All '.common_config('site', 'name').' content and data are available under the '));
- $this->element('a', array('class' => 'license',
- 'rel' => 'external license',
- 'href' => common_config('license', 'url')),
- common_config('license', 'title'));
- $this->text(' ');
- $this->text(_('license.'));
+ // TRANS: license message in footer. %1$s is the site name, %2$s is a link to the license URL, with a licence name set in configuration.
+ $notice = _('All %1$s content and data are available under the %2$s license.');
+ $link = "<a class=\"license\" rel=\"external license\" href=\"" .
+ htmlspecialchars(common_config('license', 'url')) .
+ "\">" .
+ htmlspecialchars(common_config('license', 'title')) .
+ "</a>";
+ $this->raw(sprintf(htmlspecialchars($notice),
+ htmlspecialchars(common_config('site', 'name')),
+ $link));
$this->elementEnd('p');
break;
}
function handle($argarray=null)
{
header('Vary: Accept-Encoding,Cookie');
+
$lm = $this->lastModified();
$etag = $this->etag();
+
if ($etag) {
header('ETag: ' . $etag);
}
+
if ($lm) {
header('Last-Modified: ' . date(DATE_RFC1123, $lm));
- if (array_key_exists('HTTP_IF_MODIFIED_SINCE', $_SERVER)) {
- $if_modified_since = $_SERVER['HTTP_IF_MODIFIED_SINCE'];
- $ims = strtotime($if_modified_since);
- if ($lm <= $ims) {
- $if_none_match = (array_key_exists('HTTP_IF_NONE_MATCH', $_SERVER)) ?
- $_SERVER['HTTP_IF_NONE_MATCH'] : null;
- if (!$if_none_match ||
- !$etag ||
- $this->_hasEtag($etag, $if_none_match)) {
- header('HTTP/1.1 304 Not Modified');
- // Better way to do this?
- exit(0);
- }
- }
+ if ($this->isCacheable()) {
+ header( 'Expires: ' . gmdate( 'D, d M Y H:i:s', 0 ) . ' GMT' );
+ header( "Cache-Control: private, must-revalidate, max-age=0" );
+ header( "Pragma: underwear-catapult");
}
}
+
+ if ($etag) {
+ $if_none_match = (array_key_exists('HTTP_IF_NONE_MATCH', $_SERVER)) ?
+ $_SERVER['HTTP_IF_NONE_MATCH'] : null;
+ if ($if_none_match && $this->_hasEtag($etag, $if_none_match)) {
+ header('HTTP/1.1 304 Not Modified');
+ // Better way to do this?
+ exit(0);
+ }
+ }
+
+ if ($lm && array_key_exists('HTTP_IF_MODIFIED_SINCE', $_SERVER)) {
+ $if_modified_since = $_SERVER['HTTP_IF_MODIFIED_SINCE'];
+ $ims = strtotime($if_modified_since);
+ if ($lm <= $ims) {
+ header('HTTP/1.1 304 Not Modified');
+ // Better way to do this?
+ exit(0);
+ }
+ }
+ }
+
+ /**
+ * Is this action cacheable?
+ *
+ * If the action returns a last-modified
+ *
+ * @param array $argarray is ignored since it's now passed in in prepare()
+ *
+ * @return boolean is read only action?
+ */
+
+ function isCacheable()
+ {
+ return true;
}
/**
*
* @return nothing
*/
+ // XXX: The messages in this pagination method only tailor to navigating
+ // notices. In other lists, "Previous"/"Next" type navigation is
+ // desirable, but not available.
function pagination($have_before, $have_after, $page, $action, $args=null)
{
// Does a little before-after block for next/prev page
if ($have_before || $have_after) {
$this->elementStart('dl', 'pagination');
+ // TRANS: DT element for pagination (previous/next, etc.).
$this->element('dt', null, _('Pagination'));
$this->elementStart('dd', null);
$this->elementStart('ul', array('class' => 'nav'));
$this->elementStart('li', array('class' => 'nav_prev'));
$this->element('a', array('href' => common_local_url($action, $args, $pargs),
'rel' => 'prev'),
+ // TRANS: Pagination message to go to a page displaying information more in the
+ // TRANS: present than the currently displayed information.
_('After'));
$this->elementEnd('li');
}
$this->elementStart('li', array('class' => 'nav_next'));
$this->element('a', array('href' => common_local_url($action, $args, $pargs),
'rel' => 'next'),
+ // TRANS: Pagination message to go to a page displaying information more in the
+ // TRANS: past than the currently displayed information.
_('Before'));
$this->elementEnd('li');
}
* @return void
*/
+ // XXX: Finding this type of check with the same message about 50 times.
+ // Possible to refactor?
function checkSessionToken()
{
// CSRF protection