Estas en: Home > administración

Entradas etiquetadas con administración

Cron Job WordPress

WordPress 3.x para desarrolladores: Temas y plantillas, widgets.php

0

El siguiente archivo que vamos a crear es widgets.php que generará un widget para mostrar diferentes tipos de contenido, como citas estados, etc.

 

WIDGETS.PHP

Creamos el archivo inc/widgets.php y añadimos el siguiente código:

[codesyntax lang=»php»]

<?php

/**
 * Makes a custom Widget for displaying Aside, Link, Status, and Quote Posts available with New Theme
 *
 * Learn more: http://codex.wordpress.org/Widgets_API#Developing_Widgets
 *
 * @package WordPress
 * @subpackage Nwe_Theme
 */
class New_Theme_Ephemera_Widget extends WP_Widget {

}

[/codesyntax]

Creamos la clase New_Theme_Ephemera_Widget que nos permitirá crear el widget.

Dentro de la clase añadimos los siguientes métodos.

[codesyntax lang=»php»]

<?php

	/**
	 * Constructor
	 *
	 * @return void
	 **/
	function New_Theme_Ephemera_Widget() {
		$widget_ops = array( 'classname' => 'widget_newtheme_ephemera', 'description' => __( 'Use this widget to list your recent Aside, Status, Quote, and Link posts', 'newtheme' ) );
		$this->WP_Widget( 'widget_newtheme_ephemera', __( 'New Theme Ephemera', 'newtheme' ), $widget_ops );
		$this->alt_option_name = 'widget_newtheme_ephemera';

		add_action( 'save_post', array(&$this, 'flush_widget_cache' ) );
		add_action( 'deleted_post', array(&$this, 'flush_widget_cache' ) );
		add_action( 'switch_theme', array(&$this, 'flush_widget_cache' ) );
	}

[/codesyntax]

Este método es el constructor del widget, le indica a WordPress la clase que utilizará, la desripción y el nombre del widget. Además se añaden varias acciones para volver a generar la cache cuando se guarde o elimine un post o cuando se cambie de tema.

[codesyntax lang=»php»]

<?php

	/**
	 * Outputs the HTML for this widget.
	 *
	 * @param array An array of standard parameters for widgets in this theme
	 * @param array An array of settings for this widget instance
	 * @return void Echoes it's output
	 **/
	function widget( $args, $instance ) {
		$cache = wp_cache_get( 'widget_newtheme_ephemera', 'widget' );

		if ( !is_array( $cache ) )
			$cache = array();

		if ( ! isset( $args['widget_id'] ) )
			$args['widget_id'] = null;

		if ( isset( $cache[$args['widget_id']] ) ) {
			echo $cache[$args['widget_id']];
			return;
		}

		ob_start();
		extract( $args, EXTR_SKIP );

		$title = apply_filters( 'widget_title', empty( $instance['title'] ) ? __( 'Ephemera', 'newtheme' ) : $instance['title'], $instance, $this->id_base);

		if ( ! isset( $instance['number'] ) )
			$instance['number'] = '10';

		if ( ! $number = absint( $instance['number'] ) )
 			$number = 10;

		$ephemera_args = array(
			'order' => 'DESC',
			'posts_per_page' => $number,
			'no_found_rows' => true,
			'post_status' => 'publish',
			'post__not_in' => get_option( 'sticky_posts' ),
			'tax_query' => array(
				array(
					'taxonomy' => 'post_format',
					'terms' => array( 'post-format-aside', 'post-format-link', 'post-format-status', 'post-format-quote' ),
					'field' => 'slug',
					'operator' => 'IN',
				),
			),
		);
		$ephemera = new WP_Query( $ephemera_args );

		if ( $ephemera->have_posts() ) :
			echo $before_widget;
			echo $before_title;
			echo $title; // Can set this with a widget option, or omit altogether
			echo $after_title;
			?>
			<ol>
			<?php while ( $ephemera->have_posts() ) : $ephemera->the_post(); ?>

				<?php if ( 'link' != get_post_format() ) : ?>

				<li class="widget-entry-title">
					<a href="<?php echo esc_url( get_permalink() ); ?>" title="<?php printf( esc_attr__( 'Permalink to %s', 'newtheme' ), the_title_attribute( 'echo=0' ) ); ?>" rel="bookmark"><?php the_title(); ?></a>
					<span class="comments-link">
						<?php comments_popup_link( __( '0 <span class="reply">comments &rarr;</span>', 'newtheme' ), __( '1 <span class="reply">comment &rarr;</span>', 'newtheme' ), __( '% <span class="reply">comments &rarr;</span>', 'newtheme' ) ); ?>
					</span>
				</li>

				<?php else : ?>

				<li class="widget-entry-title">
					<?php
						// Grab first link from the post content. If none found, use the post permalink as fallback.
						$link_url = newtheme_url_grabber();

						if ( empty( $link_url ) )
							$link_url = get_permalink();
					?>
					<a href="<?php echo esc_url( $link_url ); ?>" title="<?php printf( esc_attr__( 'Link to %s', 'newtheme' ), the_title_attribute( 'echo=0' ) ); ?>" rel="bookmark"><?php the_title(); ?>&nbsp;<span>&rarr;</span></a>
					<span class="comments-link">
						<?php comments_popup_link( __( '0 <span class="reply">comments &rarr;</span>', 'newtheme' ), __( '1 <span class="reply">comment &rarr;</span>', 'newtheme' ), __( '% <span class="reply">comments &rarr;</span>', 'newtheme' ) ); ?>
					</span>
				</li>

				<?php endif; ?>

			<?php endwhile; ?>
			</ol>
			<?php

			echo $after_widget;

			// Reset the post globals as this query will have stomped on it
			wp_reset_postdata();

		// end check for ephemeral posts
		endif;

		$cache[$args['widget_id']] = ob_get_flush();
		wp_cache_set( 'widget_newtheme_ephemera', $cache, 'widget' );
	}

[/codesyntax]

Este método es un poco largo, así que voy a dividirlo y explicar el código.

[codesyntax lang=»php»]

<?php

		$cache = wp_cache_get( 'widget_newtheme_ephemera', 'widget' );

		if ( !is_array( $cache ) )
			$cache = array();

		if ( ! isset( $args['widget_id'] ) )
			$args['widget_id'] = null;

		if ( isset( $cache[$args['widget_id']] ) ) {
			echo $cache[$args['widget_id']];
			return;
		}

[/codesyntax]

Primero recuperamos los datos del widget desde la caché de WordPress.

Comprobamos que en caso de que no sea un array le damos el valor de un array vacío.

Comprobamos también que $args[‘widget_id’] no esta establecido y le damos el valor null.

Por último comprobamos que la caché disponga de algún contenido para el widget, si es así se muestra ese contenido y se devuelve un return para que php no siga ejecutando el método.

[codesyntax lang=»php»]

<?php

		ob_start();
		extract( $args, EXTR_SKIP );

		$title = apply_filters( 'widget_title', empty( $instance['title'] ) ? __( 'Ephemera', 'newtheme' ) : $instance['title'], $instance, $this->id_base);

		if ( ! isset( $instance['number'] ) )
			$instance['number'] = '10';

		if ( ! $number = absint( $instance['number'] ) )
 			$number = 10;

		$ephemera_args = array(
			'order' => 'DESC',
			'posts_per_page' => $number,
			'no_found_rows' => true,
			'post_status' => 'publish',
			'post__not_in' => get_option( 'sticky_posts' ),
			'tax_query' => array(
				array(
					'taxonomy' => 'post_format',
					'terms' => array( 'post-format-aside', 'post-format-link', 'post-format-status', 'post-format-quote' ),
					'field' => 'slug',
					'operator' => 'IN',
				),
			),
		);
		$ephemera = new WP_Query( $ephemera_args );

[/codesyntax]

En el caso de que no haya contenido en la caché de WordPress, el método continuará ejecutandose.

En este extracto de código vemos como primero se abre el buffer de php utilizando la función ob_start(). Esta función permite que en vez de mostrar cualquier contenido que le siguiente, lo almacena en buffer para después poder mostrarlo donde corresponda con ob_get_flush().

A continuación se recupera el título y el número de post a mostrar.

Se crea un array con los parámetros para ejecutar una consulta SQL.

Por último se crea una nueva instancia de WP_Query() que devolverá los registros encontrados en la base de datos.

[codesyntax lang=»php»]

<?php

		if ( $ephemera->have_posts() ) :
			echo $before_widget;
			echo $before_title;
			echo $title; // Can set this with a widget option, or omit altogether
			echo $after_title;
			?>
			<ol>
			<?php while ( $ephemera->have_posts() ) : $ephemera->the_post(); ?>

				<?php if ( 'link' != get_post_format() ) : ?>

				<li class="widget-entry-title">
					<a href="<?php echo esc_url( get_permalink() ); ?>" title="<?php printf( esc_attr__( 'Permalink to %s', 'newtheme' ), the_title_attribute( 'echo=0' ) ); ?>" rel="bookmark"><?php the_title(); ?></a>
					<span class="comments-link">
						<?php comments_popup_link( __( '0 <span class="reply">comments &rarr;</span>', 'newtheme' ), __( '1 <span class="reply">comment &rarr;</span>', 'newtheme' ), __( '% <span class="reply">comments &rarr;</span>', 'newtheme' ) ); ?>
					</span>
				</li>

				<?php else : ?>

				<li class="widget-entry-title">
					<?php
						// Grab first link from the post content. If none found, use the post permalink as fallback.
						$link_url = newtheme_url_grabber();

						if ( empty( $link_url ) )
							$link_url = get_permalink();
					?>
					<a href="<?php echo esc_url( $link_url ); ?>" title="<?php printf( esc_attr__( 'Link to %s', 'newtheme' ), the_title_attribute( 'echo=0' ) ); ?>" rel="bookmark"><?php the_title(); ?>&nbsp;<span>&rarr;</span></a>
					<span class="comments-link">
						<?php comments_popup_link( __( '0 <span class="reply">comments &rarr;</span>', 'newtheme' ), __( '1 <span class="reply">comment &rarr;</span>', 'newtheme' ), __( '% <span class="reply">comments &rarr;</span>', 'newtheme' ) ); ?>
					</span>
				</li>

				<?php endif; ?>

			<?php endwhile; ?>
			</ol>
			<?php

			echo $after_widget;

			// Reset the post globals as this query will have stomped on it
			wp_reset_postdata();

		// end check for ephemeral posts
		endif;

[/codesyntax]

Se comprueba si existen post para mostrar y si es que sí se muestran diferentes valores antes de iniciar el búcle que dará formato al contenido.

Se muestra cualquier contenido posterior al widget, se reincian los post globales que esta consulta haya podido pisar.

[codesyntax lang=»php»]

<?php

		$cache[$args['widget_id']] = ob_get_flush();
		wp_cache_set( 'widget_newtheme_ephemera', $cache, 'widget' );

[/codesyntax]

Por último se guardan los datos del buffer en la caché de WordPress.

[codesyntax lang=»php»]

<?php

	/**
	 * Deals with the settings when they are saved by the admin. Here is
	 * where any validation should be dealt with.
	 **/
	function update( $new_instance, $old_instance ) {
		$instance = $old_instance;
		$instance['title'] = strip_tags( $new_instance['title'] );
		$instance['number'] = (int) $new_instance['number'];
		$this->flush_widget_cache();

		$alloptions = wp_cache_get( 'alloptions', 'options' );
		if ( isset( $alloptions['widget_newtheme_ephemera'] ) )
			delete_option( 'widget_newtheme_ephemera' );

		return $instance;
	}

[/codesyntax]

Este método permite verificar que los datos que ha introducido el administrador sean correctos y se guarden en la caché para futuros usos.

[codesyntax lang=»php»]

<?php

	function flush_widget_cache() {
		wp_cache_delete( 'widget_newtheme_ephemera', 'widget' );
	}

[/codesyntax]

Este método elimina el widget de la caché de WordPress.

[codesyntax lang=»php»]

<?php

	/**
	 * Displays the form for this widget on the Widgets page of the WP Admin area.
	 **/
	function form( $instance ) {
		$title = isset( $instance['title']) ? esc_attr( $instance['title'] ) : '';
		$number = isset( $instance['number'] ) ? absint( $instance['number'] ) : 10;
?>
			<p><label for="<?php echo esc_attr( $this->get_field_id( 'title' ) ); ?>"><?php _e( 'Title:', 'newtheme' ); ?></label>
			<input class="widefat" id="<?php echo esc_attr( $this->get_field_id( 'title' ) ); ?>" name="<?php echo esc_attr( $this->get_field_name( 'title' ) ); ?>" type="text" value="<?php echo esc_attr( $title ); ?>" /></p>

			<p><label for="<?php echo esc_attr( $this->get_field_id( 'number' ) ); ?>"><?php _e( 'Number of posts to show:', 'newtheme' ); ?></label>
			<input id="<?php echo esc_attr( $this->get_field_id( 'number' ) ); ?>" name="<?php echo esc_attr( $this->get_field_name( 'number' ) ); ?>" type="text" value="<?php echo esc_attr( $number ); ?>" size="3" /></p>
		<?php
	}

[/codesyntax]

Este último método crea el formulario donde el administrador podrá modificar el widget.

Cron Job WordPress

WordPress 3.x para desarrolladores: Temas y plantillas, theme-options.php

0

Nuestro tema va tomando poco a poco forma. Hoy vamos a crear el archivo theme-options.php que contendrá toda la lógica de las opciones de administración.

 

THEME-OPTIONS.PHP

Creamos el archivo theme-options.php y añadimos el siguiente código:

[codesyntax lang=»php»]

<?php

/**
 * Properly enqueue styles and scripts for our theme options page.
 *
 * This function is attached to the admin_enqueue_scripts action hook.
 */
function newtheme_admin_enqueue_scripts( $hook_suffix ) {
	wp_enqueue_style( 'newtheme-theme-options', get_template_directory_uri() . '/inc/theme-options.css', false, '2011-04-28' );
	wp_enqueue_script( 'newtheme-theme-options', get_template_directory_uri() . '/inc/theme-options.js', array( 'farbtastic' ), '2011-06-10' );
	wp_enqueue_style( 'farbtastic' );
}
add_action( 'admin_print_styles-appearance_page_theme_options', 'newtheme_admin_enqueue_scripts' );

[/codesyntax]

Esta función añade un archivo css y un archivo javascript a la cabecera al apartado apariencia de la administración de WordPress.

[codesyntax lang=»php»]

<?php

/**
 * Register the form setting for our newtheme_options array.
 *
 * This function is attached to the admin_init action hook.
 *
 * This call to register_setting() registers a validation callback, newtheme_theme_options_validate(),
 * which is used when the option is saved, to ensure that our option values are complete, properly
 * formatted, and safe.
 */
function newtheme_theme_options_init() {

	register_setting(
		'newtheme_options',       // Options group, see settings_fields() call in newtheme_theme_options_render_page()
		'newtheme_theme_options', // Database option, see newtheme_get_theme_options()
		'newtheme_theme_options_validate' // The sanitization callback, see newtheme_theme_options_validate()
	);

	// Register our settings field group
	add_settings_section(
		'general', // Unique identifier for the settings section
		'', // Section title (we don't want one)
		'__return_false', // Section callback (we don't want anything)
		'theme_options' // Menu slug, used to uniquely identify the page; see newtheme_theme_options_add_page()
	);

	// Register our individual settings fields
	add_settings_field(
		'color_scheme',  // Unique identifier for the field for this section
		__( 'Color Scheme', 'newtheme' ), // Setting field label
		'newtheme_settings_field_color_scheme', // Function that renders the settings field
		'theme_options', // Menu slug, used to uniquely identify the page; see newtheme_theme_options_add_page()
		'general' // Settings section. Same as the first argument in the add_settings_section() above
	);

	add_settings_field( 'link_color', __( 'Link Color',     'newtheme' ), 'newtheme_settings_field_link_color', 'theme_options', 'general' );
	add_settings_field( 'layout',     __( 'Default Layout', 'newtheme' ), 'newtheme_settings_field_layout',     'theme_options', 'general' );
}
add_action( 'admin_init', 'newtheme_theme_options_init' );

[/codesyntax]

Esta función registra la configuración por defecto del tema y añade varios apartados para la administración.

[codesyntax lang=»php»]

<?php

/**
 * Change the capability required to save the 'newtheme_options' options group.
 *
 * @see newtheme_theme_options_init() First parameter to register_setting() is the name of the options group.
 * @see newtheme_theme_options_add_page() The edit_theme_options capability is used for viewing the page.
 *
 * By default, the options groups for all registered settings require the manage_options capability.
 * This filter is required to change our theme options page to edit_theme_options instead.
 * By default, only administrators have either of these capabilities, but the desire here is
 * to allow for finer-grained control for roles and users.
 *
 * @param string $capability The capability used for the page, which is manage_options by default.
 * @return string The capability to actually use.
 */
function newtheme_option_page_capability( $capability ) {
	return 'edit_theme_options';
}
add_filter( 'option_page_capability_newtheme_options', 'newtheme_option_page_capability' );

[/codesyntax]

Esta función permite cambiar las opciones del tema. Es obligatorio para controlar los diversos usuarios y roles que tengan acceso.

[codesyntax lang=»php»]

<?php

/**
 * Add our theme options page to the admin menu, including some help documentation.
 *
 * This function is attached to the admin_menu action hook.
 */
function newtheme_theme_options_add_page() {
	$theme_page = add_theme_page(
		__( 'Theme Options', 'newtheme' ),   // Name of page
		__( 'Theme Options', 'newtheme' ),   // Label in menu
		'edit_theme_options',                    // Capability required
		'theme_options',                         // Menu slug, used to uniquely identify the page
		'newtheme_theme_options_render_page' // Function that renders the options page
	);

	if ( ! $theme_page )
		return;

	add_action( "load-$theme_page", 'newtheme_theme_options_help' );
}
add_action( 'admin_menu', 'newtheme_theme_options_add_page' );

[/codesyntax]

Añade la página de opciones de nuestro tema al menú de administración, incluyendo algo de documentación a la ayuda.

[codesyntax lang=»php»]

<?php

function newtheme_theme_options_help() {

	$help = '<p>' . __( 'Some themes provide customization options that are grouped together on a Theme Options screen. If you change themes, options may change or disappear, as they are theme-specific. Your current theme, Twenty Eleven, provides the following Theme Options:', 'newtheme' ) . '</p>' .
			'<ol>' .
				'<li>' . __( '<strong>Color Scheme</strong>: You can choose a color palette of "Light" (light background with dark text) or "Dark" (dark background with light text) for your site.', 'newtheme' ) . '</li>' .
				'<li>' . __( '<strong>Link Color</strong>: You can choose the color used for text links on your site. You can enter the HTML color or hex code, or you can choose visually by clicking the "Select a Color" button to pick from a color wheel.', 'newtheme' ) . '</li>' .
				'<li>' . __( '<strong>Default Layout</strong>: You can choose if you want your site&#8217;s default layout to have a sidebar on the left, the right, or not at all.', 'newtheme' ) . '</li>' .
			'</ol>' .
			'<p>' . __( 'Remember to click "Save Changes" to save any changes you have made to the theme options.', 'newtheme' ) . '</p>';

	$sidebar = '<p><strong>' . __( 'For more information:', 'newtheme' ) . '</strong></p>' .
		'<p>' . __( '<a href="http://codex.wordpress.org/Appearance_Theme_Options_Screen" target="_blank">Documentation on Theme Options</a>', 'newtheme' ) . '</p>' .
		'<p>' . __( '<a href="http://wordpress.org/support/" target="_blank">Support Forums</a>', 'newtheme' ) . '</p>';

	$screen = get_current_screen();

	if ( method_exists( $screen, 'add_help_tab' ) ) {
		// WordPress 3.3
		$screen->add_help_tab( array(
			'title' => __( 'Overview', 'newtheme' ),
			'id' => 'theme-options-help',
			'content' => $help,
			)
		);

		$screen->set_help_sidebar( $sidebar );
	} else {
		// WordPress 3.2
		add_contextual_help( $screen, $help . $sidebar );
	}
}

[/codesyntax]

Esta es la función que añade la ayuda que comentaba en la función anterior. Aquí además podemos ver como se añade un condicional para añadir retrocompatibilidad con versiones anteriores a la 3.3 y la 3.2.

[codesyntax lang=»php»]

<?php

/**
 * Returns an array of color schemes registered for New Theme.
 */
function newtheme_color_schemes() {
	$color_scheme_options = array(
		'light' => array(
			'value' => 'light',
			'label' => __( 'Light', 'newtheme' ),
			'thumbnail' => get_template_directory_uri() . '/inc/images/light.png',
			'default_link_color' => '#1b8be0',
		),
		'dark' => array(
			'value' => 'dark',
			'label' => __( 'Dark', 'newtheme' ),
			'thumbnail' => get_template_directory_uri() . '/inc/images/dark.png',
			'default_link_color' => '#e4741f',
		),
	);

	return apply_filters( 'newtheme_color_schemes', $color_scheme_options );
}

[/codesyntax]

Esta función devuelve un array con los esquemas de color para cada versión del tema.

[codesyntax lang=»php»]

<?php

/**
 * Returns an array of layout options registered for New Theme.
 */
function newtheme_layouts() {
	$layout_options = array(
		'content-sidebar' => array(
			'value' => 'content-sidebar',
			'label' => __( 'Content on left', 'newtheme' ),
			'thumbnail' => get_template_directory_uri() . '/inc/images/content-sidebar.png',
		),
		'sidebar-content' => array(
			'value' => 'sidebar-content',
			'label' => __( 'Content on right', 'newtheme' ),
			'thumbnail' => get_template_directory_uri() . '/inc/images/sidebar-content.png',
		),
		'content' => array(
			'value' => 'content',
			'label' => __( 'One-column, no sidebar', 'newtheme' ),
			'thumbnail' => get_template_directory_uri() . '/inc/images/content.png',
		),
	);

	return apply_filters( 'newtheme_layouts', $layout_options );
}

[/codesyntax]

Devuelve un array con las opciones para cada tipo de estructura del diseño.

[codesyntax lang=»php»]

<?php

/**
 * Returns the default options for New Theme.
 */
function newtheme_get_default_theme_options() {
	$default_theme_options = array(
		'color_scheme' => 'light',
		'link_color'   => newtheme_get_default_link_color( 'light' ),
		'theme_layout' => 'content-sidebar',
	);

	if ( is_rtl() )
 		$default_theme_options['theme_layout'] = 'sidebar-content';

	return apply_filters( 'newtheme_default_theme_options', $default_theme_options );
}

[/codesyntax]

Devuelve las opciones por defecto del tema.

[codesyntax lang=»php»]

<?php

/**
 * Returns the default link color for New Theme, based on color scheme.
 *
 *
 * @param $string $color_scheme Color scheme. Defaults to the active color scheme.
 * @return $string Color.
*/
function newtheme_get_default_link_color( $color_scheme = null ) {
	if ( null === $color_scheme ) {
		$options = newtheme_get_theme_options();
		$color_scheme = $options['color_scheme'];
	}

	$color_schemes = newtheme_color_schemes();
	if ( ! isset( $color_schemes[ $color_scheme ] ) )
		return false;

	return $color_schemes[ $color_scheme ]['default_link_color'];
}

[/codesyntax]

Devuelve el color por defecto para los vínculos.

[codesyntax lang=»php»]

<?php

/**
 * Returns the options array for New Theme.
 */
function newtheme_get_theme_options() {
	return get_option( 'newtheme_theme_options', newtheme_get_default_theme_options() );
}

[/codesyntax]

Devuelve un array con todas las opciones del tema.

[codesyntax lang=»php»]

<?php

/**
 * Renders the Color Scheme setting field.
 */
function newtheme_settings_field_color_scheme() {
	$options = newtheme_get_theme_options();

	foreach ( newtheme_color_schemes() as $scheme ) {
	?>
	<div class="layout image-radio-option color-scheme">
	<label class="description">
		<input type="radio" name="newtheme_theme_options[color_scheme]" value="<?php echo esc_attr( $scheme['value'] ); ?>" <?php checked( $options['color_scheme'], $scheme['value'] ); ?> />
		<input type="hidden" id="default-color-<?php echo esc_attr( $scheme['value'] ); ?>" value="<?php echo esc_attr( $scheme['default_link_color'] ); ?>" />
		<span>
			<img src="<?php echo esc_url( $scheme['thumbnail'] ); ?>" width="136" height="122" alt="" />
			<?php echo $scheme['label']; ?>
		</span>
	</label>
	</div>
	<?php
	}
}

[/codesyntax]

Esta función genera el grupo de radio buttons que permitirá elegir entre un esquema de color u otro.

[codesyntax lang=»php»]

<?php

/**
 * Renders the Link Color setting field.
 */
function newtheme_settings_field_link_color() {
	$options = newtheme_get_theme_options();
	?>
	<input type="text" name="newtheme_theme_options[link_color]" id="link-color" value="<?php echo esc_attr( $options['link_color'] ); ?>" />
	<a href="#" class="pickcolor hide-if-no-js" id="link-color-example"></a>
	<input type="button" class="pickcolor button hide-if-no-js" value="<?php esc_attr_e( 'Select a Color', 'newtheme' ); ?>" />
	<div id="colorPickerDiv" style="z-index: 100; background:#eee; border:1px solid #ccc; position:absolute; display:none;"></div>
	<br />
	<span><?php printf( __( 'Default color: %s', 'newtheme' ), '<span id="default-color">' . newtheme_get_default_link_color( $options['color_scheme'] ) . '</span>' ); ?></span>
	<?php
}

[/codesyntax]

Esta función genera el formulario para poder elegir el color de los vínculos.

[codesyntax lang=»php»]

<?php

/**
 * Renders the Layout setting field.
 */
function newtheme_settings_field_layout() {
	$options = newtheme_get_theme_options();
	foreach ( newtheme_layouts() as $layout ) {
		?>
		<div class="layout image-radio-option theme-layout">
		<label class="description">
			<input type="radio" name="newtheme_theme_options[theme_layout]" value="<?php echo esc_attr( $layout['value'] ); ?>" <?php checked( $options['theme_layout'], $layout['value'] ); ?> />
			<span>
				<img src="<?php echo esc_url( $layout['thumbnail'] ); ?>" width="136" height="122" alt="" />
				<?php echo $layout['label']; ?>
			</span>
		</label>
		</div>
		<?php
	}
}

[/codesyntax]

Esta función genera el campo para elegir la estructura del blog.

[codesyntax lang=»php»]

<?php

/**
 * Returns the options array for New Theme.
 */
function newtheme_theme_options_render_page() {
	?>
	<div class="wrap">
		<?php screen_icon(); ?>
		<?php $theme_name = function_exists( 'wp_get_theme' ) ? wp_get_theme() : get_current_theme(); ?>
		<h2><?php printf( __( '%s Theme Options', 'newtheme' ), $theme_name ); ?></h2>
		<?php settings_errors(); ?>

		<form method="post" action="options.php">
			<?php
				settings_fields( 'newtheme_options' );
				do_settings_sections( 'theme_options' );
				submit_button();
			?>
		</form>
	</div>
	<?php
}

[/codesyntax]

Función que genera todo el formulario de opciones.

[codesyntax lang=»php»]

<?php

/**
 * Sanitize and validate form input. Accepts an array, return a sanitized array.
 *
 * @see newtheme_theme_options_init()
 * @todo set up Reset Options action
 */
function newtheme_theme_options_validate( $input ) {
	$output = $defaults = newtheme_get_default_theme_options();

	// Color scheme must be in our array of color scheme options
	if ( isset( $input['color_scheme'] ) && array_key_exists( $input['color_scheme'], newtheme_color_schemes() ) )
		$output['color_scheme'] = $input['color_scheme'];

	// Our defaults for the link color may have changed, based on the color scheme.
	$output['link_color'] = $defaults['link_color'] = newtheme_get_default_link_color( $output['color_scheme'] );

	// Link color must be 3 or 6 hexadecimal characters
	if ( isset( $input['link_color'] ) && preg_match( '/^#?([a-f0-9]{3}){1,2}$/i', $input['link_color'] ) )
		$output['link_color'] = '#' . strtolower( ltrim( $input['link_color'], '#' ) );

	// Theme layout must be in our array of theme layout options
	if ( isset( $input['theme_layout'] ) && array_key_exists( $input['theme_layout'], newtheme_layouts() ) )
		$output['theme_layout'] = $input['theme_layout'];

	return apply_filters( 'newtheme_theme_options_validate', $output, $input, $defaults );
}

[/codesyntax]

Esta función valida que los datos del formulario son correctos.

[codesyntax lang=»php»]

<?php

/**
 * Enqueue the styles for the current color scheme.
 */
function newtheme_enqueue_color_scheme() {
	$options = newtheme_get_theme_options();
	$color_scheme = $options['color_scheme'];

	if ( 'dark' == $color_scheme )
		wp_enqueue_style( 'dark', get_template_directory_uri() . '/colors/dark.css', array(), null );

	do_action( 'newtheme_enqueue_color_scheme', $color_scheme );
}
add_action( 'wp_enqueue_scripts', 'newtheme_enqueue_color_scheme' );

[/codesyntax]

Función que cambiará el estilo actual de la página dependiendo del color de esquema elegido.

[codesyntax lang=»php»]

<?php

/**
 * Add a style block to the theme for the current link color.
 *
 * This function is attached to the wp_head action hook.
 */
function newtheme_print_link_color_style() {
	$options = newtheme_get_theme_options();
	$link_color = $options['link_color'];

	$default_options = newtheme_get_default_theme_options();

	// Don't do anything if the current link color is the default.
	if ( $default_options['link_color'] == $link_color )
		return;
?>
	<style>
		/* Link color */
		a,
		#site-title a:focus,
		#site-title a:hover,
		#site-title a:active,
		.entry-title a:hover,
		.entry-title a:focus,
		.entry-title a:active,
		.widget_newtheme_ephemera .comments-link a:hover,
		section.recent-posts .other-recent-posts a[rel="bookmark"]:hover,
		section.recent-posts .other-recent-posts .comments-link a:hover,
		.format-image footer.entry-meta a:hover,
		#site-generator a:hover {
			color: <?php echo $link_color; ?>;
		}
		section.recent-posts .other-recent-posts .comments-link a:hover {
			border-color: <?php echo $link_color; ?>;
		}
		article.feature-image.small .entry-summary p a:hover,
		.entry-header .comments-link a:hover,
		.entry-header .comments-link a:focus,
		.entry-header .comments-link a:active,
		.feature-slider a.active {
			background-color: <?php echo $link_color; ?>;
		}
	</style>
<?php
}
add_action( 'wp_head', 'newtheme_print_link_color_style' );

[/codesyntax]

Función que añadirá el color a los vínculos a través de los estilos si este no es el mismo que el de defecto.

[codesyntax lang=»php»]

<?php

/**
 * Adds New Theme layout classes to the array of body classes.
 */
function newtheme_layout_classes( $existing_classes ) {
	$options = newtheme_get_theme_options();
	$current_layout = $options['theme_layout'];

	if ( in_array( $current_layout, array( 'content-sidebar', 'sidebar-content' ) ) )
		$classes = array( 'two-column' );
	else
		$classes = array( 'one-column' );

	if ( 'content-sidebar' == $current_layout )
		$classes[] = 'right-sidebar';
	elseif ( 'sidebar-content' == $current_layout )
		$classes[] = 'left-sidebar';
	else
		$classes[] = $current_layout;

	$classes = apply_filters( 'newtheme_layout_classes', $classes, $current_layout );

	return array_merge( $existing_classes, $classes );
}
add_filter( 'body_class', 'newtheme_layout_classes' );

[/codesyntax]

Esta función añade las clases correspondientes a la etiqueta body dependiendo de la estructura de blog elegida.

[codesyntax lang=»php»]

<?php

/**
 * Implements New Theme theme options into Theme Customizer
 *
 * @param $wp_customize Theme Customizer object
 * @return void
 */
function newtheme_customize_register( $wp_customize ) {
	$wp_customize->get_setting( 'blogname' )->transport = 'postMessage';
	$wp_customize->get_setting( 'blogdescription' )->transport = 'postMessage';

	$options  = newtheme_get_theme_options();
	$defaults = newtheme_get_default_theme_options();

	$wp_customize->add_setting( 'newtheme_theme_options[color_scheme]', array(
		'default'    => $defaults['color_scheme'],
		'type'       => 'option',
		'capability' => 'edit_theme_options',
	) );

	$schemes = newtheme_color_schemes();
	$choices = array();
	foreach ( $schemes as $scheme ) {
		$choices[ $scheme['value'] ] = $scheme['label'];
	}

	$wp_customize->add_control( 'newtheme_color_scheme', array(
		'label'    => __( 'Color Scheme', 'newtheme' ),
		'section'  => 'colors',
		'settings' => 'newtheme_theme_options[color_scheme]',
		'type'     => 'radio',
		'choices'  => $choices,
		'priority' => 5,
	) );

	// Link Color (added to Color Scheme section in Theme Customizer)
	$wp_customize->add_setting( 'newtheme_theme_options[link_color]', array(
		'default'           => newtheme_get_default_link_color( $options['color_scheme'] ),
		'type'              => 'option',
		'sanitize_callback' => 'sanitize_hex_color',
		'capability'        => 'edit_theme_options',
	) );

	$wp_customize->add_control( new WP_Customize_Color_Control( $wp_customize, 'link_color', array(
		'label'    => __( 'Link Color', 'newtheme' ),
		'section'  => 'colors',
		'settings' => 'newtheme_theme_options[link_color]',
	) ) );

	// Default Layout
	$wp_customize->add_section( 'newtheme_layout', array(
		'title'    => __( 'Layout', 'newtheme' ),
		'priority' => 50,
	) );

	$wp_customize->add_setting( 'newtheme_theme_options[theme_layout]', array(
		'type'              => 'option',
		'default'           => $defaults['theme_layout'],
		'sanitize_callback' => 'sanitize_key',
	) );

	$layouts = newtheme_layouts();
	$choices = array();
	foreach ( $layouts as $layout ) {
		$choices[$layout['value']] = $layout['label'];
	}

	$wp_customize->add_control( 'newtheme_theme_options[theme_layout]', array(
		'section'    => 'newtheme_layout',
		'type'       => 'radio',
		'choices'    => $choices,
	) );
}
add_action( 'customize_register', 'newtheme_customize_register' );

[/codesyntax]

Esta función añade todas las opciones al personalizador de temas.

[codesyntax lang=»php»]

<?php

/**
 * Bind JS handlers to make Theme Customizer preview reload changes asynchronously.
 * Used with blogname and blogdescription.
 */
function newtheme_customize_preview_js() {
	wp_enqueue_script( 'newtheme-customizer', get_template_directory_uri() . '/inc/theme-customizer.js', array( 'customize-preview' ), '20120523', true );
}
add_action( 'customize_preview_init', 'newtheme_customize_preview_js' );

[/codesyntax]

Esta función indica a WordPress que añada un archivo javascript para la previsualización de la página para poder ver los cambios del tema.

GestAuto 0.0.2.0 pre-alpha

5

Nueva versión del gestor de autoescuelas con los siguientes cambios:

Nueva pestaña Contabilidad. Ahora la aplicación permitirá gestionar de una forma básica la contabilidad de la autoescuela (ingresos y gastos).

Alertas de alumnos. Ahora la aplicación mostrará una alerta cada vez que se inicie la aplicación indicando si existen alumnos que  falten por pagar algún servicio.

Sistema de pago. Ahora al añadir un alumno a un curso se mostrará un mensaje para iniciar el pago del curso, permitiendo elegir entre tarjeta o efectivo y las cuotas en las que se dividirá el pago.

 

Se han corregido algunos errores y se ha actualizado la base de datos para las nuevas características.

 

Descargar: GestAuto 0.0.2.0 pre-alpha

Logo Cassandra

Cassandra 1.x y PHP para desarrolladores SQL: Cassandra Cluster Admin, el phpMyAdmin de Cassandra

3

En el anterior post expliqué el funcionamiento de la consola de Cassandra y como trabajar con ella. En este post explicaré como hacer lo mismo de una forma más rápida y fácil.

La razón de que no haya empezado ha explicar como se utiliza Cassandra desde PHP, es que primero hay que conocer cómo funciona Cassandra, su modelo de datos (que ya hemos visto) y algunos comandos básicos para ir aprendiendo a guardar y recuperar datos. El próximo post ya trataré el funcionamiento de PHPCassa y empezaremos a programar.

Este post será bastante ligerito. Explicaré principalmente como hacer lo mismo que hicimos por consola pero de modo gráfico. CassAdmin, como yo le llamo, tiene más opciones de edición para los keyspaces y column families de los que vamos a ver (igual que ocurría con la consola), pero solo tocaremos las opciones más habituales.

 

INSTALACIÓN

Lo típico en estos casos. Descargar. Descomprimir y ejecutar. Descargamos los archivos desde el repositorio de git: https://github.com/sebgiroux/Cassandra-Cluster-Admin, o a través de git o como archivo comprimido. Como más te guste.

Proceso para descargar Cassandra Cluster Admin

Página de descargas del administrador

Ahora descomprimimos a una carpeta dentro de nuestro servidor web, ya que trabajamos con una aplicación programada en PHP.

Si tienes Cassandra instalado en otro equipo que no sea en local, una máquina virtual por ejemplo, tendrás que cambiar la ip a la que se conecta cassAdmin. Es bastante sencillo. Para ello debes modificar el archivo includes/config.inc.php y sustituir la ip de localhost (127.0.0.1)  por la ip del equipo en el que tengas instalado Cassandra:

Archivo config.inc.php

Como verás en la captura, yo utilizo la ip local 192.168.1.10 que pertenece a una máquina virtual. Si tuviera instalado Cassandra en  el mismo equipo la ip a la que debería apuntar sería 127.0.0.1. El puerto no lo modificamos.

Una vez instalado y configurado (si fuese el caso) probamos a acceder desde nuestro navegador. Debería mostrarte algo como esto:

Página principal de Cassandra Cluster Admin

CREAR KEYSPACES

Como has podido ver, en la página principal del administrador ya aparece un keyspace, llamado system, perteneciente a Cassandra, con lo que lo mantendremos como está.

Justo encima tenemos un botón para crear un nuevo keyspace (Create a new keyspace). Lo pulsamos.

Formulario para crear un keyspace

Solo nos pide tres parámetros a rellenar:


Keyspace name
: El nombre del keyspace a crear.
Replication factor: Es el número de servidores o instancias de Cassandra de los que se debe guardar un registro u obtener una respuesta al recuperar algún registro.
Strategy: Es la estrategia que seguirá Cassandra para guardar los datos. En el caso de tener varios servidores o centro de datos diferenciados entre sí, se aplicará una estrategia u otra para que los datos no se pierdan. Más info: http://answers.oreilly.com/topic/2408-replica-placement-strategies-when-using-cassandra/ 

En nuestro caso escribiremos los siguientes valores:

Formulario para crear un keyspace con datos

Pulsamos en Create keyspace y nos llevará a la página principal:

Página principal mostrando el keyspace que acabamos de crear

Pulsamos sobre el keyspace que acabamos de crear y nos llevará a la siguiente página:

Página de detalle del keyspace my_keyspace

Aquí podemos ver información relativa al keyspace y al anillo (o cluster) en el que se encuentra guardado. También nos permite editar el keyspace o eliminarlo, pero la opción más interesante es la de crear nuevas column families (Create a new column family).

 

CREAR UNA COLUMN FAMILY

Dentro del keyspace pulsamos sobre el botón Create a new column family, nos mostrará lo siguiente:

Formulario para crear una column family

 

Primero crearemos una column family standard con los siguientes datos:

Datos para crear la primera column family

Para crear una column family solo son necesarios tres parámetros:


Column Family Name
: El nombre de la column family que vamos a crear.
Column Type: El tipo de column family que vamos a crear (Standard o Super).
Comparator Type: El comparador principal de las columnas. Es decir, la codificación que tendrán los datos dentro de la column family.

Pulsamos en Create Column Family y en la página de nuestro keyspace se habrá añadido una nueva column family:

Detalle de la column family creada

 

AÑADIR REGISTROS A UNA COLUMN FAMILY STANDARD

Ahora toca guardar registros en la BD.
Como comenté en post anteriores Cassandra no necesita conocer los campos de las tablas (nuestras column families) ya que los creamos cada vez que añadimos un registro.

Primero en la página principal del keyspace haz click en el nombre de la column family. Te aparecerá lo siguiente:

 

Detalle de la página principal de la column family creada

En esta página te aparecerá, además de la información referente a la column family, los siguientes botones:


Browse Data
: Para mostrar un listado de los registros que contiene la column family.
Create Secondary Index: Para crear indices secundarios. Parecido a los indices de MySQL.
Get Key: Para buscar una clave o registro concreto.
Insert Row: Para insertar un nuevo registro.
Edit Column Family: Para editar los parámetros de la column family.
Truncate Column Family: Para eliminar los registros de la column family sin eliminar esta.
Drop Column Family: Para eliminar la column family y su contenido.

Pulsamos en Insert Row. Nos aparecerá lo siguiente:

Formulario para insertar registros

Siempre que añadamos un nuevo registro deberemos indicar una key diferente que deberá ser única, sino cassAdmin pensará que lo que quieres hacer es actualizar ese registro. Añadimos los siguientes datos al formulario:

Formulario para insertar registros con datos

 

Para añadir otra fila de cuadro de texto solo tienes que pulsar el botón Add…
Volvemos a la página principal de la column family y pulsamos en Browse Data. Aquí veremos un listado con los registros que hayamos añadido:

 

Listado de registros

 

CREAR UNA COLUMN FAMILY SUPER Y AÑADIR REGISTROS

El proceso para crear una column family Super es idéntico a las column family Standard, solo hay que cambiar un valor a la hora de crearla:

Creación de una column family Super

Entramos en la página principal de la nueva column family y pulsamos en Insert Row. Aquí veremos que el formulario a cambiado un poco, nos aparece un nuevo campo llamado Super Column Name y un nuevo botón encima del formulario, Add Super Column:

Formulario para insertar registros de una column family super

Las column family Super son como las muñecas matrioskas, esas figuras que si las abrías había otra igual dentro, y dentro de esa otra más, y otra, etc. Algo parecido sucede con estas column family. Disponemos de una key (nuestra primera matrioska) que contiene a las super columns (segunda matrioska), que a su vez contienen las columnas clave:valor.

Añadamos un registro para verlo:

Datos para crear una super column

Si nos vamos a Browse Data:

Listado de registros en una column family Super

Como ves, ahora las columns se agruparían dentro de la super column. Añadiré más registros para que lo veas mejor:

Listado de registros en una column family Super

¿Ves? Las keys agrupan a las super columns y estas a su vez a las columns.

 

Creo que esto es suficiente para que conozcas el funcionamiento de Cassandra Cluster Admin. Quedarían algunas cosillas, como editar registros, hacer búsquedas o eliminar registros, pero eso es bastante sencillo (a excepción de las Secondary Index y las Counter Columns que trataré más adelante).

Para cualquier duda o problema déjala en los comentarios.

Logo Cassandra

Cassandra y PHP para desarrolladores SQL: Cassandra Cluster Admin, el phpMyAdmin de Cassandra

4

En el anterior post expliqué el funcionamiento de la consola de Cassandra y como trabajar con ella. En este post explicaré como hacer lo mismo de una forma más rápida y fácil.

La razón de que no haya empezado ha explicar como se utiliza Cassandra desde PHP, es que primero hay que conocer cómo funciona Cassandra, su modelo de datos (que ya hemos visto) y algunos comandos básicos para ir aprendiendo a guardar y recuperar datos. El próximo post ya trataré el funcionamiento de phpCassa y empezaremos a programar.

Este post será bastante ligerito. Explicaré principalmente como hacer lo mismo que hicimos por consola pero de modo gráfico. CassAdmin, como yo le llamo, tiene más opciones de edición para los keyspaces y column families de los que vamos a ver (igual que ocurría con la consola), pero solo tocaremos las opciones más habituales.

 

INSTALACIÓN

Lo típico en estos casos. Descargar. Descomprimir y ejecutar. Descargamos los archivos desde el repositorio de git: https://github.com/sebgiroux/Cassandra-Cluster-Admin, o a través de git o como archivo comprimido. Como más te guste.

Repositorio de Cassandra Cluster Admin

Página de descargas del administrador

Ahora descomprimimos a una carpeta dentro de nuestro servidor web, ya que trabajamos con una aplicación programada en PHP.

Si tienes Cassandra instalado en otro equipo que no sea en local, una máquina virtual por ejemplo, tendrás que cambiar la ip a la que se conecta cassAdmin. Es bastante sencillo. Para ello debes modificar el archivo includes/config.inc.php y sustituir la ip de localhost (127.0.0.1)  por la ip del equipo en el que tengas instalado Cassandra:

Archivo config.inc.php

Como verás en la captura, yo utilizo la ip local 192.168.1.10 que pertenece a una máquina virtual. Si tuviera instalado Cassandra en  el mismo equipo la ip a la que debería apuntar sería 127.0.0.1. El puerto no lo modificamos.

Una vez instalado y configurado (si fuese el caso) probamos a acceder desde nuestro navegador. Debería mostrarte algo como esto:

Página principal de Cassandra Cluster Admin

CREAR KEYSPACES

Como has podido ver, en la página principal del administrador ya aparece un keyspace, llamado system, perteneciente a Cassandra, con lo que lo mantendremos como está.

Justo encima tenemos un botón para crear un nuevo keyspace (Create a new keyspace). Lo pulsamos.

Formulario para crear un keyspace

Solo nos pide tres parámetros a rellenar:


Keyspace name
: El nombre del keyspace a crear.
Replication factor: Es el número de servidores o instancias de Cassandra de los que se debe guardar un registro u obtener una respuesta al recuperar algún registro.
Strategy: Es la estrategia que seguirá Cassandra para guardar los datos. En el caso de tener varios servidores o centro de datos diferenciados entre sí, se aplicará una estrategia u otra para que los datos no se pierdan. Más info: http://answers.oreilly.com/topic/2408-replica-placement-strategies-when-using-cassandra/ 

En nuestro caso escribiremos los siguientes valores:

Formulario para crear un keyspace con datos

Pulsamos en Create keyspace y nos llevará a la página principal:

Página principal mostrando el keyspace que acabamos de crear

Pulsamos sobre el keyspace que acabamos de crear y nos llevará a la siguiente página:

Página de detalle del keyspace my_keyspace

Aquí podemos ver información relativa al keyspace y al anillo (o cluster) en el que se encuentra guardado. También nos permite editar el keyspace o eliminarlo, pero la opción más interesante es la de crear nuevas column families (Create a new column family).

 

CREAR UNA COLUMN FAMILY

Dentro del keyspace pulsamos sobre el botón Create a new column family, nos mostrará lo siguiente:

Formulario para crear una column family

 

Primero crearemos una column family standard con los siguientes datos:

Datos para crear la primera column family

Para crear una column family solo son necesarios tres parámetros:


Column Family Name
: El nombre de la column family que vamos a crear.
Column Type: El tipo de column family que vamos a crear (Standard o Super).
Comparator Type: El comparador principal de las columnas. Es decir, la codificación que tendrán los datos dentro de la column family.

Pulsamos en Create Column Family y en la página de nuestro keyspace se habrá añadido una nueva column family:

Detalle de la column family creada

 

AÑADIR REGISTROS A UNA COLUMN FAMILY STANDARD

Ahora toca guardar registros en la BD.
Como comenté en post anteriores Cassandra no necesita conocer los campos de las tablas (nuestras column families) ya que los creamos cada vez que añadimos un registro.

Primero en la página principal del keyspace haz click en el nombre de la column family. Te aparecerá lo siguiente:

 

Detalle de la página principal de la column family creada

En esta página te aparecerá, además de la información referente a la column family, los siguientes botones:


Browse Data
: Para mostrar un listado de los registros que contiene la column family.
Create Secondary Index: Para crear indices secundarios. Parecido a los indices de MySQL.
Get Key: Para buscar una clave o registro concreto.
Insert Row: Para insertar un nuevo registro.
Edit Column Family: Para editar los parámetros de la column family.
Truncate Column Family: Para eliminar los registros de la column family sin eliminar esta.
Drop Column Family: Para eliminar la column family y su contenido.

Pulsamos en Insert Row. Nos aparecerá lo siguiente:

Formulario para insertar registros

Siempre que añadamos un nuevo registro deberemos indicar una key diferente que deberá ser única, sino cassAdmin pensará que lo que quieres hacer es actualizar ese registro. Añadimos los siguientes datos al formulario:

Formulario para insertar registros con datos

 

Para añadir otra fila de cuadro de texto solo tienes que pulsar el botón Add…
Volvemos a la página principal de la column family y pulsamos en Browse Data. Aquí veremos un listado con los registros que hayamos añadido:

 

Listado de registros

 

CREAR UNA COLUMN FAMILY SUPER Y AÑADIR REGISTROS

El proceso para crear una column family Super es idéntico a las column family Standard, solo hay que cambiar un valor a la hora de crearla:

Creación de una column family Super

Entramos en la página principal de la nueva column family y pulsamos en Insert Row. Aquí veremos que el formulario a cambiado un poco, nos aparece un nuevo campo llamado Super Column Name y un nuevo botón encima del formulario, Add Super Column:

Formulario para insertar registros de una column family super

Las column family Super son como las muñecas matrioskas, esas figuras que si las abrías había otra igual dentro, y dentro de esa otra más, y otra, etc. Algo parecido sucede con estas column family. Disponemos de una key (nuestra primera matrioska) que contiene a las super columns (segunda matrioska), que a su vez contienen las columnas clave:valor.

Añadamos un registro para verlo:

Datos para crear una super column

Si nos vamos a Browse Data:

Listado de registros en una column family Super

Como ves, ahora las columns se agruparían dentro de la super column. Añadiré más registros para que lo veas mejor:

Listado de registros en una column family Super

¿Ves? Las keys agrupan a las super columns y estas a su vez a las columns.

 

Creo que esto es suficiente para que conozcas el funcionamiento de Cassandra Cluster Admin. Quedarían algunas cosillas, como editar registros, hacer búsquedas o eliminar registros, pero eso es bastante sencillo (a excepción de las Secondary Index y las Counter Columns que trataré más adelante).

Para cualquier duda o problema déjala en los comentarios.

GestAuto, programa para gestión de autoescuelas

16

LA APLICACIÓN SE HA RELANZADO, SI QUIERES AYUDAR  PROBANDO LA APLICACIÓN O APORTANDO SUGERENCIAS SIGUE EL SIGUIENTE LINK: GestAuto 0.0.1.0 pre-alpha, la aplicación de gestión de autoescuelas open source se relanza

Hace un tiempo comencé a desarrollar una aplicación para la gestión de autoescuelas, que por desgracia no tengo tiempo para continuar desarrollando, y me daba pena que el trabajo de muchos meses se quedase olvidado en un rincón del disco duro. Al final me he decidido a publicar lo que tengo hecho y bajo la licencia GPL v3.

¡OJO! LA APLICACIÓN NO ESTÁ TERMINADA, (ya me gustaría) AUNQUE SI SE PUEDE PROBAR SIN QUE GENERE ERRORES O LA APLICACIÓN SE CIERRE. PERO REPITO, NO ESTÁ TERMINADA, Y NO ME HAGO RESPONSABLE DE LA PERDIDA DE DATOS QUE PUEDA PRODUCIR UN ERROR EN LA APLICACIÓN.

Datos técnicos de la aplicación:

  • Está programado en VB .NET (sí lo se, no es lo mejor para programar, pero a falta de conocimientos de C/C++, no me quedaba otra), está divido por clases y algún componente que tuve que crear. El código, no está precisamente muy comentado, (lo siento), aunque podréis preguntarme cualquier duda que tengais sobre el código.
  • Base de datos Access (sí, también lo se, no es precisamente lo mejor), aunque sería relativamente sencillo crear una clase para conectar con una base de datos MySQL, por ejemplo, ya que la conexion a la BD y los métodos de acceso a los datos, están en una clase separada del resto del código.
  • A través de MONO se podría ejecutar en GNU/Linux.

Características de la aplicación:

  • Puede manejar multiples autoescuelas (No recuerdo si comprobé que lo hacía correctamente, pero en principio estaba pensado para ello).
  • Puede manejar multiples tasas, matriculas, precios, ofertas, cursos, clases,  etc.
  • Puede elegirse un profesor para las clases teóricas y otro para las prácticas.
  • Impresión de documentos oficiales (Creo que solo imprimía la prueba de aptitud, y únicamente para la Comunidad de Madrid)
  • Listados de alumnos, profesores, vehículos, autoescuelas, etc.
  • Gestión de alumnos, profesores, autoescuelas y vehículos (Esta última parte la deshabilité del programa ya que aun no estaba acabada, aunque en el código si aparece y se puede habilitar la pestaña).
Ir arriba