$title ) {
// Check if the link matches the current URI base, if true, add 'current' class.
$class = gp_startswith( $current_uri, $link ) ? 'current' : '';
$html .= '' . $title . '';
}
return $html;
}
function gp_nav_menu_items( $location = 'main' ) {
$items = array();
if ( 'main' === $location ) {
$items[ gp_url( '/projects' ) ] = __( 'Projects', 'glotpress' );
$items[ gp_url( '/languages' ) ] = __( 'Locales', 'glotpress' );
} elseif ( 'side' === $location ) {
if ( is_user_logged_in() ) {
$user = wp_get_current_user();
$items[ gp_url_profile( $user->user_nicename ) ] = __( 'Profile', 'glotpress' );
$items[ gp_url( '/settings' ) ] = __( 'Settings', 'glotpress' );
$items[ esc_url( wp_logout_url( gp_url_current() ) ) ] = __( 'Log out', 'glotpress' );
} else {
$items[ esc_url( wp_login_url( gp_url_current() ) ) ] = __( 'Log in', 'glotpress' );
}
}
/**
* Filter the list of navigation menu items.
*
* @since 1.0.0
*
* @param array $items Menu items. URL as the key, menu label as the value.
* @param string $location Location of the menu.
*/
return apply_filters( 'gp_nav_menu_items', $items, $location );
}
function gp_tmpl_filter_args( $args ) {
$clean_args = array();
foreach ( $args as $k => $v ) {
if ( '_' != $k[0] && 'GLOBALS' != $k && ! gp_startswith( $k, 'HTTP' ) && ! gp_startswith( $k, 'PHP' ) ) {
$clean_args[ $k ] = $v;
}
}
return $clean_args;
}
function gp_tmpl_404( $args = array() ) {
gp_tmpl_load(
'404',
$args + array(
'title' => __( 'Not Found', 'glotpress' ),
'http_status' => 404,
)
);
exit();
}
function gp_title( $title = null ) {
if ( ! is_null( $title ) ) {
add_filter(
'gp_title',
function() use ( $title ) {
return $title;
},
5
);
} else {
/**
* Filter the title of a page.
*
* @since 1.0.0
*
* @param string $title The title of a page.
*/
return apply_filters( 'gp_title', '' );
}
}
function gp_breadcrumb( $breadcrumb = null, $args = array() ) {
if ( $breadcrumb ) {
$breadcrumb = gp_array_flatten( $breadcrumb );
add_filter(
'gp_breadcrumb_items',
function( $breadcrumbs ) use ( $breadcrumb ) {
return array_merge( $breadcrumbs, $breadcrumb );
},
1
);
} else {
/**
* Filter the list of breadcrumb navigation items.
*
* @since 1.0.0
*
* @param array $breadcrumb_items Breadcrumb items as HTML string.
*/
$breadcrumbs = apply_filters( 'gp_breadcrumb_items', array() );
if ( $breadcrumbs ) {
$defaults = array(
/* translators: separates links in the navigation breadcrumb */
'before' => '
',
'after' => '',
'breadcrumb-template' => '',
);
$args = array_merge( $defaults, $args );
$whole_breadcrumb = '';
foreach ( $breadcrumbs as $breadcrumb ) {
$whole_breadcrumb .= $args['before'] . $breadcrumb . $args['after'];
}
$whole_breadcrumb = str_replace( '{breadcrumb}', $whole_breadcrumb, $args['breadcrumb-template'] );
/**
* Filter the breadcrumb HTML output.
*
* @since 1.0.0
*
* @param string $whole_breadcrumb Breadcrumb HTML.
*/
return apply_filters( 'gp_breadcrumb', $whole_breadcrumb );
}
}
}
function gp_project_names_from_root( $leaf_project ) {
$names = array();
$path_from_root = array_reverse( $leaf_project->path_to_root() );
foreach ( $path_from_root as $project ) {
$names[] = esc_html( $project->name );
}
$project_path = implode( ' | ', $names );
return $project_path;
}
function gp_project_links_from_root( $leaf_project ) {
if ( 0 === $leaf_project->id ) {
return array();
}
$links = array();
$path_from_root = array_reverse( $leaf_project->path_to_root() );
$links[] = empty( $path_from_root ) ? __( 'Projects', 'glotpress' ) : gp_link_get( gp_url( '/projects' ), __( 'Projects', 'glotpress' ) );
foreach ( $path_from_root as $project ) {
$links[] = gp_link_project_get( $project, esc_html( $project->name ) );
}
return $links;
}
function gp_breadcrumb_project( $project ) {
return gp_breadcrumb( gp_project_links_from_root( $project ) );
}
function gp_js_focus_on( $html_id ) {
return '';
}
function gp_select( $name_and_id, $options, $selected_key, $attrs = array() ) {
$attributes = gp_html_attributes( $attrs );
$attributes = $attributes ? " $attributes" : '';
$res = "\n";
return $res;
}
function gp_radio_buttons( $name, $radio_buttons, $checked_key ) {
$res = '';
foreach ( $radio_buttons as $value => $label ) {
$checked = checked( $value, $checked_key, false );
// TODO: something more flexible than
$res .= "\t ";
$res .= "
\n";
}
return $res;
}
function gp_pagination( $page, $per_page, $objects ) {
$surrounding = 2;
$first = $prev_dots = $prev_pages = $next_pages = $next_dots = $last = '';
$page = intval( $page ) ? intval( $page ) : 1;
$pages = ceil( $objects / $per_page );
if ( $page > $pages ) {
return '';
}
if ( $page > 1 ) {
$prev = gp_link_get( add_query_arg( array( 'page' => $page - 1 ) ), '←', array( 'class' => 'previous' ) );
} else {
$prev = '←';
}
if ( $page < $pages ) {
$next = gp_link_get( add_query_arg( array( 'page' => $page + 1 ) ), '→', array( 'class' => 'next' ) );
} else {
$next = '→';
}
$current = '' . $page . '';
if ( $page > 1 ) {
$prev_pages = array();
foreach ( range( max( 1, $page - $surrounding ), $page - 1 ) as $prev_page ) {
$prev_pages[] = gp_link_get( add_query_arg( array( 'page' => $prev_page ) ), $prev_page );
}
$prev_pages = implode( ' ', $prev_pages );
if ( $page - $surrounding > 1 ) {
$prev_dots = '…';
}
}
if ( $page < $pages ) {
$next_pages = array();
foreach ( range( $page + 1, min( $pages, $page + $surrounding ) ) as $next_page ) {
$next_pages[] = gp_link_get( add_query_arg( array( 'page' => $next_page ) ), $next_page );
}
$next_pages = implode( ' ', $next_pages );
if ( $page + $surrounding < $pages ) {
$next_dots = '…';
}
}
if ( $prev_dots ) {
$first = gp_link_get( add_query_arg( array( 'page' => 1 ) ), 1 );
}
if ( $next_dots ) {
$last = gp_link_get( add_query_arg( array( 'page' => $pages ) ), $pages );
}
$html = <<
$prev
$first
$prev_dots
$prev_pages
$current
$next_pages
$next_dots
$last
$next
HTML;
/**
* Filter the pagination HTML output.
*
* @since 1.0.0
*
* @param string $html The pagination HTML.
* @param int $page Current page number.
* @param int $per_page Objects per page.
* @param int $objects Total number of objects to page.
*/
return apply_filters( 'gp_pagination', $html, $page, $per_page, $objects );
}
function gp_html_attributes( $attrs ) {
$attrs = wp_parse_args( $attrs );
$strings = array();
foreach ( $attrs as $key => $value ) {
$strings[] = $key . '="' . esc_attr( $value ) . '"';
}
return implode( ' ', $strings );
}
function gp_attrs_add_class( $attrs, $class_name ) {
$attrs['class'] = isset( $attrs['class'] ) ? $attrs['class'] . ' ' . $class_name : $class_name;
return $attrs;
}
/**
* Returns HTML markup for a select element for all locales of a project.
*
* @since 1.0.0
*
* @param int $project_id ID of a project.
* @param string $name_and_id Name and ID of the select element.
* @param string $selected_slug Slug of the current selected locale.
* @param array $attrs Extra attributes.
*
* @return string HTML markup for a select element.
*/
function gp_locales_by_project_dropdown( $project_id, $name_and_id, $selected_slug = null, $attrs = array() ) {
$locales = GP_Locales::locales();
if ( null != $project_id ) {
$sets = GP::$translation_set->by_project_id( $project_id );
$temp_locales = array();
foreach ( $sets as $set ) {
$temp_locales[ $set->locale ] = $locales[ $set->locale ];
}
if ( count( $temp_locales ) > 0 ) {
$locales = $temp_locales;
}
}
ksort( $locales );
$options = array( '' => __( '— Locale —', 'glotpress' ) );
foreach ( $locales as $key => $locale ) {
$options[ $key ] = sprintf( '%s — %s', $locale->slug, $locale->english_name );
}
return gp_select( $name_and_id, $options, $selected_slug, $attrs );
}
/**
* Returns HTML markup for a select element for all locales.
*
* @since 1.0.0
*
* @param string $name_and_id Name and ID of the select element.
* @param string $selected_slug Slug of the current selected locale.
* @param array $attrs Extra attributes.
*
* @return string HTML markup for a select element.
*/
function gp_locales_dropdown( $name_and_id, $selected_slug = null, $attrs = array() ) {
return gp_locales_by_project_dropdown( null, $name_and_id, $selected_slug, $attrs );
}
/**
* Returns HTML markup for a select element for projects.
*
* @since 1.0.0
*
* @param string $name_and_id Name and ID of the select element.
* @param string $selected_project_id The project id to mark as the currently selected.
* @param array $attrs Extra attributes.
* @param array $exclude An array of project IDs to exclude from the list.
* @param array $exclude_no_parent Exclude the "No Parent" option from the list of projects.
*
* @return string HTML markup for a select element.
*/
function gp_projects_dropdown( $name_and_id, $selected_project_id = null, $attrs = array(), $exclude = array(), $exclude_no_parent = false ) {
if ( ! is_array( $exclude ) ) {
$exclude = array( $exclude );
}
$projects = GP::$project->all();
// TODO: mark which nodes are editable by the current user
$tree = array();
$top = array();
foreach ( $projects as $p ) {
$tree[ $p->id ]['self'] = $p;
if ( $p->parent_project_id ) {
$tree[ $p->parent_project_id ]['children'][] = $p->id;
} else {
$top[] = $p->id;
}
}
if ( ! $exclude_no_parent ) {
$options = array( '' => __( '— No parent —', 'glotpress' ) );
} else {
$options = array();
}
foreach ( $top as $top_id ) {
$stack = array( $top_id );
while ( ! empty( $stack ) ) {
$id = array_pop( $stack );
if ( in_array( $id, $exclude, true ) ) {
continue;
}
$tree[ $id ]['level'] = gp_array_get( $tree[ $id ], 'level', 0 );
$options[ $id ] = str_repeat( '-', $tree[ $id ]['level'] ) . $tree[ $id ]['self']->name;
foreach ( gp_array_get( $tree[ $id ], 'children', array() ) as $child_id ) {
$stack[] = $child_id;
$tree[ $child_id ]['level'] = $tree[ $id ]['level'] + 1;
}
}
}
return gp_select( $name_and_id, $options, $selected_project_id, $attrs );
}
function gp_array_of_things_to_json( $array ) {
return wp_json_encode(
array_map(
function( $thing ) {
return $thing->fields();
},
$array
)
);
}
function gp_array_of_array_of_things_to_json( $array ) {
$map_to_fields = function( $array ) {
return array_map(
function( $thing ) {
return $thing->fields();
},
$array
);
};
return wp_json_encode( array_map( $map_to_fields, $array ) );
}
function things_to_fields( $data ) {
if ( is_array( $data ) ) {
foreach ( $data as $item_id => $item ) {
$data[ $item_id ] = things_to_fields( $item );
}
} elseif ( $data instanceof GP_Thing ) {
$data = $data->fields();
}
return $data;
}
function gp_preferred_sans_serif_style_tag( $locale ) {
if ( ! $locale->preferred_sans_serif_font_family ) {
return;
}
?>
$project->id ) ), __( 'New Sub-Project', 'glotpress' ) ),
gp_link_get( gp_url( '/sets/-new', array( 'project_id' => $project->id ) ), __( 'New Translation Set', 'glotpress' ) ),
gp_link_get( gp_url_project( $project, array( '-mass-create-sets' ) ), __( 'Mass-create Translation Sets', 'glotpress' ) ),
gp_link_get( gp_url_project( $project, '-branch' ), __( 'Branch project', 'glotpress' ) ),
gp_link_get( gp_url_project( $project, '-delete' ), __( 'Delete project', 'glotpress' ) ),
);
/**
* Project action links.
*
* @since 1.0.0
*
* @param array $actions Links as HTML strings.
* @param GP_Project $project The project.
*/
$actions = apply_filters( 'gp_project_actions', $actions, $project );
echo '';
foreach ( $actions as $action ) {
// phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
echo '- ' . $action . '
';
}
if ( $translation_sets ) {
echo '- ' . gp_project_options_form( $project ) . '
';
}
echo '
';
}
function gp_project_options_form( $project ) {
return '
' . __( 'Personal project options', 'glotpress' ) . ' ↓
';
}
function gp_entry_actions( $seperator = ' • ' ) {
$actions = array(
' ' .
' ' .
'
',
);
/**
* Filters entry action links.
*
* @since 1.0.0
*
* @param array $actions Links as HTML strings.
*/
$actions = apply_filters( 'gp_entry_actions', $actions );
// phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
echo implode( $seperator, $actions );
}
/**
* Generates a list of classes to be added to the translation row, based on translation entry properties.
*
* @since 2.2.0
*
* @param Translation_Entry $translation The translation entry object for the row.
*
* @return array
*/
function gp_get_translation_row_classes( $translation ) {
$classes = array();
$classes[] = $translation->translation_status ? 'status-' . $translation->translation_status : 'untranslated';
$classes[] = 'priority-' . gp_array_get( GP::$original->get_static( 'priorities' ), $translation->priority );
$classes[] = $translation->warnings ? 'has-warnings' : 'no-warnings';
$classes[] = count( array_filter( $translation->translations, 'gp_is_not_null' ) ) > 0 ? 'has-translations' : 'no-translations';
/**
* Filters the list of CSS classes for a translation row
*
* @since 2.2.0
*
* @param array $classes An array of translation row classes.
* @param Translation_Entry $translation The translation entry object.
*/
$classes = apply_filters( 'gp_translation_row_classes', $classes, $translation );
return $classes;
}
/**
* Outputs space separated list of classes for the translation row, based on translation entry properties.
*
* @since 2.2.0
*
* @param Translation_Entry $translation The translation entry object for the row.
*
* @return void
*/
function gp_translation_row_classes( $translation ) {
$classes = gp_get_translation_row_classes( $translation );
echo esc_attr( implode( ' ', $classes ) );
}