@if( $errors->any())
<b-alert show variant="danger">
<ul>
@foreach($errors->all() as $error)
<li>
{{ $error }}
</li>
@endforeach
</ul>
</b-alert>
@else
<b-alert show>
Por favor, ingresa tus datos
</b-alert>
@endif
curso laravel realtime messenger - parte 6 - creando usuarios auth
luego de haber instalado el modulo de auth
debemos ejecutar las migrations, pero antes debemos crear nuestra base de datos y configurar los parametros de conexion en el archivo .env
DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=messenger
DB_USERNAME=root
DB_PASSWORD=
creamos la base de datos
mysql -u root -p
create database messenger
vamos anecesitar tener algunos usuarios de prueba creados inicialmente para poder trabajar.
entonces
vamos a database\seeds\DatabaseSeeder.php
y descomentamos la linea
$this->call(UsersTableSeeder::class);
y ejecutamos la sgt sentencia para crear esa clase seeder
php artisan make:seeder UsersTableSeeder
ahora editamos el archivo creado:
use Illuminate\Database\Seeder;
use App\User;
class UsersTableSeeder extends Seeder
{
/**
* Run the database seeds.
*
* @return void
*/
public function run()
{
User::create([
'name'=>'israel',
'email'=>'israelbazan76@gmail.com',
'password' => bcrypt('123123')
])
}
}
ahora si ya podemos ejecutar las migraciones....pero antes para evitar que nos de este error
pero nos va a salir el siguiente error
Syntax error or access violation: 1071 Specified key was too long; max key length is 767 bytes
para resolver editar app\Providers\AppServiceProvider.php
public function boot()
{
\Illuminate\Support\Facades\Schema::defaultStringLength(191);
}
y finalmente
php artisan migrate --seed
debemos ejecutar las migrations, pero antes debemos crear nuestra base de datos y configurar los parametros de conexion en el archivo .env
DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=messenger
DB_USERNAME=root
DB_PASSWORD=
creamos la base de datos
mysql -u root -p
create database messenger
vamos anecesitar tener algunos usuarios de prueba creados inicialmente para poder trabajar.
entonces
vamos a database\seeds\DatabaseSeeder.php
y descomentamos la linea
$this->call(UsersTableSeeder::class);
y ejecutamos la sgt sentencia para crear esa clase seeder
php artisan make:seeder UsersTableSeeder
ahora editamos el archivo creado:
use Illuminate\Database\Seeder;
use App\User;
class UsersTableSeeder extends Seeder
{
/**
* Run the database seeds.
*
* @return void
*/
public function run()
{
User::create([
'name'=>'israel',
'email'=>'israelbazan76@gmail.com',
'password' => bcrypt('123123')
])
}
}
ahora si ya podemos ejecutar las migraciones....pero antes para evitar que nos de este error
pero nos va a salir el siguiente error
Syntax error or access violation: 1071 Specified key was too long; max key length is 767 bytes
para resolver editar app\Providers\AppServiceProvider.php
public function boot()
{
\Illuminate\Support\Facades\Schema::defaultStringLength(191);
}
y finalmente
php artisan migrate --seed
curso laravel realtime messenger - parte 5 - adaptando cabecera navegador a bootstrap-vue
la cabecera de navegacion se encuentra en
resources\views\layouts\app.blade.php
asi que debemos editar ese archivo,
quedandonos
<form id="logout-form" action="{{ route('logout') }}" method="POST" style="display: none;">
{{ csrf_field() }}
</form>
<div id="app">
<b-navbar toggleable="md" type="dark" variant="info">
<b-navbar-toggle target="nav_collapse"></b-navbar-toggle>
<b-navbar-brand href="{{ url('/') }}">
{{ config('app.name', 'Laravel') }}
</b-navbar-brand>
<b-collapse is-nav id="nav_collapse">
<!-- Right aligned nav items -->
<b-navbar-nav class="ml-auto">
@guest
<b-nav-item href="{{ route('login') }}">Ingreso</b-nav-item>
<b-nav-item href="{{ route('register') }}">Registro</b-nav-item>
@else
<b-nav-item-dropdown right>
<!-- Using button-content slot -->
<template slot="button-content">
<em>{{ Auth::user()->name }}</em>
</template>
<b-dropdown-item @click="logout">Salir</b-dropdown-item>
</b-nav-item-dropdown>
@endguest
</b-navbar-nav>
</b-collapse>
</b-navbar>
@yield('content')
</div>
donde el link para salir llama a una funcion llamada logout.
que la vamos a definir en
resources\assets\js\app.js
asi:
const app = new Vue({
el: '#app',
methods:{
logout(){
document.getElementById('logout-form').submit();
}
}
});
el cual llamar al evento submit del formulario que hemos sacado afuera del cuerpo principal
resources\views\layouts\app.blade.php
asi que debemos editar ese archivo,
quedandonos
<form id="logout-form" action="{{ route('logout') }}" method="POST" style="display: none;">
{{ csrf_field() }}
</form>
<div id="app">
<b-navbar toggleable="md" type="dark" variant="info">
<b-navbar-toggle target="nav_collapse"></b-navbar-toggle>
<b-navbar-brand href="{{ url('/') }}">
{{ config('app.name', 'Laravel') }}
</b-navbar-brand>
<b-collapse is-nav id="nav_collapse">
<!-- Right aligned nav items -->
<b-navbar-nav class="ml-auto">
@guest
<b-nav-item href="{{ route('login') }}">Ingreso</b-nav-item>
<b-nav-item href="{{ route('register') }}">Registro</b-nav-item>
@else
<b-nav-item-dropdown right>
<!-- Using button-content slot -->
<template slot="button-content">
<em>{{ Auth::user()->name }}</em>
</template>
<b-dropdown-item @click="logout">Salir</b-dropdown-item>
</b-nav-item-dropdown>
@endguest
</b-navbar-nav>
</b-collapse>
</b-navbar>
@yield('content')
</div>
donde el link para salir llama a una funcion llamada logout.
que la vamos a definir en
resources\assets\js\app.js
asi:
const app = new Vue({
el: '#app',
methods:{
logout(){
document.getElementById('logout-form').submit();
}
}
});
el cual llamar al evento submit del formulario que hemos sacado afuera del cuerpo principal
curso laravel realtime messenger parte 3 - adaptando login a bootstrap-vue
originalmente tenemos:
<div class="container">
<div class="row">
<div class="col-md-8 col-md-offset-2">
donde col-md-8 significa que el sistema de grilla de 12 columnas. el cuerpo va a ocupar 8 y va a usarse 2 columnas vacias a ambos lados. para que de esa manera quede centrado.
reemplazar por:
<b-container>
<b-row>
<b-col>
</b-col>
<b-col cols="8">
</b-col>
<b-col>
</b-col>
</b-row>
</b-container>
o mejor por:
<b-container>
<b-row align-h="center">
<b-col cols="8">
...
</b-col>
</b-row>
</b-container>
lo reemplazaremos por el componente b-card
<b-card header="featured"
header-tag="header"
footer="Card Footer"
footer-tag="footer"
title="Title">
<p class="card-text">Header and footers using props.</p>
<b-button href="#" variant="primary">Go somewhere</b-button>
</b-card>
<div class="container">
<div class="row">
<div class="col-md-8 col-md-offset-2">
donde col-md-8 significa que el sistema de grilla de 12 columnas. el cuerpo va a ocupar 8 y va a usarse 2 columnas vacias a ambos lados. para que de esa manera quede centrado.
reemplazar por:
<b-container>
<b-row>
<b-col>
</b-col>
<b-col cols="8">
</b-col>
<b-col>
</b-col>
</b-row>
</b-container>
o mejor por:
<b-container>
<b-row align-h="center">
<b-col cols="8">
...
</b-col>
</b-row>
</b-container>
lo que esta dentro del b-col cols="8"
<div class="panel panel-default">
<div class="panel-heading">Login</div>
<div class="panel-body">
//----aqui esta el formulario
</div>
</div>lo reemplazaremos por el componente b-card
<b-card header="featured"
header-tag="header"
footer="Card Footer"
footer-tag="footer"
title="Title">
<p class="card-text">Header and footers using props.</p>
<b-button href="#" variant="primary">Go somewhere</b-button>
</b-card>
curso laravel realtime messenger - parte 2 bootstrap-vue
instalamos el scafolding para manejo de usuarios (login y registro)
desde la carpeta del proyecto:
php artisan make:auth
--------------------
instalamos bootstrap-vue
npm i bootstrap-vue
en resources/js/app.js
compilamos
php run dev
para probar si realmente ya hemos cargado bootstrap-vue
podemos editar la pagina de login y le pegamos al codigo un bloque que hace referencia a un componente. en este caso al de alert.
resources\views\auth\login.blade.php
<b-alert show>
Por favor, ingresa tus datos
</b-alert>
desde la carpeta del proyecto:
php artisan make:auth
--------------------
instalamos bootstrap-vue
npm i bootstrap-vue
en resources/js/app.js
import Vue from 'vue'
import BootstrapVue from 'bootstrap-vue'
Vue.use(BootstrapVue);
y en resources/js/bootstrap.js
import 'bootstrap/dist/css/bootstrap.css'
import 'bootstrap-vue/dist/bootstrap-vue.css'
Hay que volver a crear en resources la carpeta assets/sass y adentro app.scss en donde pegaremos las gsts lineas:
@import "~bootstrap/dist/css/bootstrap.css"; @import "~bootstrap-vue/dist/bootstrap-vue.css";
luego, en webpack.mix.js, debera quedar asi:
mix.js('resources/assets/js/app.js', 'public/js')
.sass('resources/assets/sass/app.scss', 'public/css');
php run dev
para probar si realmente ya hemos cargado bootstrap-vue
podemos editar la pagina de login y le pegamos al codigo un bloque que hace referencia a un componente. en este caso al de alert.
resources\views\auth\login.blade.php
<b-alert show>
Por favor, ingresa tus datos
</b-alert>
curso laravel realtime messenger - parte 1 configuraciones iniciales
tenemos que bajarnos las librerias de javascript necesarias, esto lo hacemos con npm
pero antes editamos el archivo donde se manejan estas dependencias
package.json
dejamos unicamente estas:
"devDependencies": {
"axios": "^0.17",
"cross-env": "^5.1",
"laravel-mix": "^1.0",
"vue": "^2.5.7"
}
como hemos sacado las referencias a jquery, bootstrap-sass y lodash
las quitamos tambien del archivo
resources\assets\js\bootstrap.js
y en el archivo
webpack.mix.js
lo dejamos asi:
mix.js('resources/assets/js/app.js', 'public/js');
--le hemos quitado la parte donde trabajaba con la carpeta sass, de hecho tambien podriamos eliminarla del proyecto.
resources\assets\sass
ahora si, compilamos el proyecto:
npm run dev
esto generara en public/js el archivo app.js
como se indicaba en webpack.mix.js
pero antes editamos el archivo donde se manejan estas dependencias
package.json
dejamos unicamente estas:
"devDependencies": {
"axios": "^0.17",
"cross-env": "^5.1",
"laravel-mix": "^1.0",
"vue": "^2.5.7"
}
como hemos sacado las referencias a jquery, bootstrap-sass y lodash
las quitamos tambien del archivo
resources\assets\js\bootstrap.js
y en el archivo
webpack.mix.js
lo dejamos asi:
mix.js('resources/assets/js/app.js', 'public/js');
--le hemos quitado la parte donde trabajaba con la carpeta sass, de hecho tambien podriamos eliminarla del proyecto.
resources\assets\sass
ahora si, compilamos el proyecto:
npm run dev
esto generara en public/js el archivo app.js
como se indicaba en webpack.mix.js
laravel sincronizar proyecto con github
desde la carpeta del proyecto nuevo:
1)
git init
2)
git add -A
3)
git commit -m "initial commit"
4)
ir a la pagina de github
-crear un nuevo repositorio
-copiar la direccion https del repositorio (p.e https://github.com/israelbazan76/messenger.git)
5)
en la consola:
git remote add origin https://github.com/israelbazan76/messenger.git
6)
git push origin master
1)
git init
2)
git add -A
3)
git commit -m "initial commit"
4)
ir a la pagina de github
-crear un nuevo repositorio
-copiar la direccion https del repositorio (p.e https://github.com/israelbazan76/messenger.git)
5)
en la consola:
git remote add origin https://github.com/israelbazan76/messenger.git
6)
git push origin master
laravel crear proyecto con composer
si trabajamos con xampp:
1)
abrir una consola e ir hasta la carpeta httdocs,
composer create-project --prefer-dist laravel/laravel nombre_del_proyecto "5.5.*"
2)
- ir a la carpeta del proyecto creado
- renombrar el archivo oculto .env.example por .env:
rename .env.example .env
3) generar la clave de la aplicacion
php artisan key:generate
------------ opcional --------------
crear un virtual host
1) editar el archivo
C:\xampp729\apache\conf\extra\httpd-vhosts.conf
<VirtualHost *:80>
ServerName messenger.local
DocumentRoot "C:/xampp729/htdocs/messenger/public"
</VirtualHost>
2)editar el archivo
C:\Windows\System32\drivers\etc\hosts
127.0.0.1 messenger.local
----------------------------------------
ya podemos levantar el servidor apache
y en el navegador acceder a la url:
http://messenger.local:80
laravel 5.7 notificaciones database pusher
1) ir a pusher.com y registrarse
2) crear una new app
donde
frontend: vanilla js
backend: laravel
cluster: us2
3) instalar pusher en nuestra aplicacion
composer require pusher/pusher-php-server
4) ir a la pestana de App Keys
y tomar la informacion de alli para completar los datos en .env
PUSHER_APP_ID=
PUSHER_APP_KEY=
PUSHER_APP_SECRET=
PUSHER_APP_CLUSTER=
y en resources/js/bootstrap.js
import Echo from 'laravel-echo'
window.Pusher = require('pusher-js');
window.Echo = new Echo({
broadcaster: 'pusher',
key: 'XXXXXX',
cluster: 'us2',
encrypted: true
});
5)Crear en resource/components NotificationComponent.vue
<template>
<li class="nav-item d-md-down-none">
<a class="nav-link" href="#" data-toggle="dropdown">
<i class="icon-bell"></i>
<span class="badge badge-pill badge-danger">{{notifications.length}}</span>
</a>
<div class="dropdown-menu dropdown-menu-right">
<div class="dropdown-header text-center">
<strong>Notificaciones</strong>
</div>
<li v-for="notification in notifications" :key="notifications.id">
<a class="dropdown-item" href="#">
<i class="fa fa-envelope-o"></i> {{notification.data.datos.articulos.titulo}}
<span class="badge badge-success">{{notification.data.datos.articulos.activos}}</span>
</a>
</li>
</div>
</li>
</template>
<script>
export default {
props: ['notifications'],
data(){
return {
}
}
}
</script>
6) agregar este componente en resources/js/app.js
Vue.component('notification', require('./components/NotificationComponent.vue'));
const app = new Vue({
el: '#app',
data:{
menu:0,
notifications:[]
},
created(){
let me = this;
axios.get('/notifications').then(function(response){
console.log(response.data)
me.notifications=response.data;
}).catch(function(error){
console.log(error);
});
}
});
7) en la plantilla principal reemplazar el codigo de cabecera donde se mostrabalas notificaciones por este componente:
principal.blade.php
<notification :notifications="notifications"></notification>
8) vamos a usar el canal "database" que es donde la informacion de las notificaciones se guardan en una tabla
php artisan notifications:table
php artisan migrate
como en laravel cada notificacion es representada por una simple clase, vamos a crear una
php artisan make:notification NotifyAdmin
lo que creara la carpeta Notifications dentro de App y dentro la clase NotifyAdmin
class NotifyAdmin extends Notification
{
public $GlobalDatos;
/**
* Create a new notification instance.
*
* @return void
*/
public function __construct(Array $datos)
{
$this->GlobalDatos = $datos;
}
public function via($notifiable)
{
return ['database'];
}
public function toDatabase($notifiable)
{
return ['datos' => $this->GlobalDatos];
}
8) creamos NotificationController:
public function getAllByUser()
{
$user = \Auth::user();
//return Notification::where('notifiable_id','=',$user->id)->get();
return $user->notifications;
}
9)
creamos la ruta de este metorod en web.php
Route::get('/notifications','NotificationController@getAllByUser')->middleware('auth');
10) en este ejemplo cada vez que se crea un nuevo producto se va a crear una notificacion por cada usuario con la cantidad de articulos activos (condicion=1)
entonces en ArticuloController->store
...despues del save
$numActivos = DB::table('articulos')->where('condicion','=','1')->count();
$arregloDatos = [
'articulos' => [
'activos' =>$numActivos,
'titulo' => 'Articulos activos'
]
];
$users = \App\User::all();
foreach ($users as $user) {
\App\User::findOrFail($user->id)->notify(new \App\Notifications\NotifyAdmin($arregloDatos));
}
10) en este ejemplo cada vez que se crea un nuevo producto se va a crear una notificacion por cada usuario con la cantidad de articulos activos (condicion=1)
entonces en ArticuloController->store
...despues del save
$numActivos = DB::table('articulos')->where('condicion','=','1')->count();
$arregloDatos = [
'articulos' => [
'activos' =>$numActivos,
'titulo' => 'Articulos activos'
]
];
$users = \App\User::all();
foreach ($users as $user) {
\App\User::findOrFail($user->id)->notify(new \App\Notifications\NotifyAdmin($arregloDatos));
}
Abrir varias terminales de Ubuntu en Windows
instalar TMUX
1)
sudo apt-get install tmux
2)
tipear tmux
3)
por ejemplo podemos ir al disco C
cd /mnt/c
y desde ahi
1)
sudo apt-get install tmux
2)
tipear tmux
3)
por ejemplo podemos ir al disco C
cd /mnt/c
y desde ahi
Here is a list of a few basic tmux commands:
Ctrl+b "
— split pane horizontally.Ctrl+b %
— split pane vertically.Ctrl+b arrow key
— switch pane.- Hold
Ctrl+b
, don’t release it and hold one of the arrow keys — resize pane. Ctrl+b c
— (c)reate a new window.Ctrl+b n
— move to the (n)ext window.Ctrl+b p
— move to the (p)revious window.
Other thing worth knowing is that scrolling is enabled by pressing
Ctrl+b PgUp/PgDown
instalar ubuntu 16.04 en windows
1) ir a Settings -> Update & Security -> For Developers
2) habilitar Developer Mode
3) ir a Control Panel -> Programs -> Turn Windows features on or off
4) buscar y habilitar la opcion Windows Subsystem for Linux
5) reinicar la PC.
6) ir al Windows Store buscar Ubuntu e instalar Ubuntu 16.04 LTS
7) abrir Ubuntu e indicar el usuario y password para Ubuntu (no es necesario que coincidan con los de windows)
ubuntu 16.04 instalar php7.x
sudo apt-add-repository ppa:ondrej/php
sudo apt-get update
sudo apt-get install php7.x
ubuntu 16.04 instalar npm
curl -sL https://deb.nodesource.com/setup_10.x | sudo -E bash - sudo apt-get install -y nodejs
laravel login y logout
Route::group(['middleware' => ['guest']], function () {
Route::get('/', 'Auth\LoginController@showLoginForm');
Route::match(['get','post'],'/login', 'Auth\LoginController@login')->name('login');
});
Route::match(['get','post'],'/logout','Auth\LoginController@logout')->name('logout')->middleware('auth');
Route::match(['get','post'],'/ se uso en vez de post
para evitar la exception MethodNotAllowedHttpException que dispara cuando, estando logueado, se tipea en la url /login
laravel maneja "automaticamente" a traves del middleware RedirectIfAuthenticated que cuando se esta logueado y se tipee en la url
la barra "/" o "/login" te redireccione a la ruta que hayas denominado como "home"
aunque el logout se puede manejar para evitar ataques Cross se va a manejar a traves del method POST, entonces en la vista
<div class="dropdown-menu dropdown-menu-right">
<div class="dropdown-header text-center">
<strong>Cuenta</strong>
</div>
<a class="dropdown-item" href="#"><i class="fa fa-user"></i> Perfil</a>
<a class="dropdown-item" href="#" onclick="event.preventDefault(); document.getElementById('frm-logout').submit();"><i class="fa fa-lock"></i> Cerrar sesión</a>
</div>
<form id="frm-logout" action="{{ route('logout') }}" method="POST" style="display: none;">
{{ csrf_field() }}
</form>
y en el controller:
public function logout(Request $request)
{
if ($request->isMethod('post')) {
Auth::logout();
$request->session()->invalidate();
return redirect('/');
}
return back();
}
Route::get('/', 'Auth\LoginController@showLoginForm');
Route::match(['get','post'],'/login', 'Auth\LoginController@login')->name('login');
});
Route::match(['get','post'],'/logout','Auth\LoginController@logout')->name('logout')->middleware('auth');
Route::match(['get','post'],'/ se uso en vez de post
para evitar la exception MethodNotAllowedHttpException que dispara cuando, estando logueado, se tipea en la url /login
laravel maneja "automaticamente" a traves del middleware RedirectIfAuthenticated que cuando se esta logueado y se tipee en la url
la barra "/" o "/login" te redireccione a la ruta que hayas denominado como "home"
aunque el logout se puede manejar para evitar ataques Cross se va a manejar a traves del method POST, entonces en la vista
<div class="dropdown-menu dropdown-menu-right">
<div class="dropdown-header text-center">
<strong>Cuenta</strong>
</div>
<a class="dropdown-item" href="#"><i class="fa fa-user"></i> Perfil</a>
<a class="dropdown-item" href="#" onclick="event.preventDefault(); document.getElementById('frm-logout').submit();"><i class="fa fa-lock"></i> Cerrar sesión</a>
</div>
<form id="frm-logout" action="{{ route('logout') }}" method="POST" style="display: none;">
{{ csrf_field() }}
</form>
y en el controller:
public function logout(Request $request)
{
if ($request->isMethod('post')) {
Auth::logout();
$request->session()->invalidate();
return redirect('/');
}
return back();
}
laravel crear data de prueba
por ejemplo para crear usuarios
1) creamos una clase seeder
(la cual se creara dentro de database/seeds)
2) editamos el cuerpo de la clase USersTableSeeder
para indicar que modelo usaremos para crear registros y la cantidad de registros a crear
use Illuminate\Database\Seeder;
use App\User;
class UsersTableSeeder extends Seeder
{
/**
* Run the database seeds.
*
* @return void
*/
public function run()
{
//
factory(User::class, 5)->create();
}
}
3) ahora debemos crear la clase factory que se encuentra en database/factories
use Faker\Generator as Faker;
$factory->define(App\User::class, function (Faker $faker) {
return [
'name' => $faker->name,
'email' => $faker->unique()->safeEmail,
'password' => '$2y$10$TKh8H1.PfQx37YgCzwiKb.KjNyWgaHb9cbcoQgdIVFlYg7B77UdFm', // secret
'remember_token' => str_random(10),
];
});
4) EN la clase DatabaseSeeder, indicamos las llamadas a los seeders que se invocaran con una llamada general
class DatabaseSeeder extends Seeder
{
/**
* Seed the application's database.
*
* @return void
*/
public function run()
{
$this->call(UsersTableSeeder::class);
}
}
5)
para llamar al run de databaseSeeder
1) creamos una clase seeder
php artisan make:seeder UsersTableSeeder
(la cual se creara dentro de database/seeds)
2) editamos el cuerpo de la clase USersTableSeeder
para indicar que modelo usaremos para crear registros y la cantidad de registros a crear
use Illuminate\Database\Seeder;
use App\User;
class UsersTableSeeder extends Seeder
{
/**
* Run the database seeds.
*
* @return void
*/
public function run()
{
//
factory(User::class, 5)->create();
}
}
3) ahora debemos crear la clase factory que se encuentra en database/factories
use Faker\Generator as Faker;
$factory->define(App\User::class, function (Faker $faker) {
return [
'name' => $faker->name,
'email' => $faker->unique()->safeEmail,
'password' => '$2y$10$TKh8H1.PfQx37YgCzwiKb.KjNyWgaHb9cbcoQgdIVFlYg7B77UdFm', // secret
'remember_token' => str_random(10),
];
});
class DatabaseSeeder extends Seeder
{
/**
* Seed the application's database.
*
* @return void
*/
public function run()
{
$this->call(UsersTableSeeder::class);
}
}
5)
para llamar al run de databaseSeeder
php artisan db:seedpara llamar al run del seeder en particular
php artisan db:seed --class=UsersTableSeeder
laravel localization language
modificar
config/app.php
'locale' => 'es'
debe existir, sino hay que crearla, la carpeta
resources/lang/es
si usamos en un controller por ejemplo la siguiente
return back()->withErrors(['usuario'=>trans('auth.failed')]);
quiere decir que existe el archivo auth.php en resources/lang/es
con la sgt estructura:
<?php
return [
'failed' => 'Los datos ingresados no coinciden con nuestros registros.',
];
no olvidar limpiar la cache de la config:
php artisan config:cache
se puede descargar la carpeta es desde este repositorio
https://github.com/hosmelq/lang-spanish
react native 0.57 crear y ejecutar una primer aplicacion
1)
desde la consola
react-native init MiAplicacion
2) ir a la carpeta creada de la aplicacion y desde ahi:
npm add @babel/runtime
3) ir a android Studio
file->open
ir hasta la carpeta del proyecto y click en el archivo "android"
4) abrir AVD Manager
del listado de Your Virtual Devices click en el boton verde de play para lanzar ese emulador
5) desde la consola y dentro de la carpeta de la aplicacion creada:
react-native run-android
6) Si todo esta ok deberia aparecer en la pantalla del emulador el siguiente texto de prueba:
Welcome to React Native!
To get started, edit App.js
Double tap R on your keyboard to reload,
Shake or press menu button for dev menu
el cual se encuentra en App.js en la raiz del proyecto
desde la consola
react-native init MiAplicacion
2) ir a la carpeta creada de la aplicacion y desde ahi:
npm add @babel/runtime
3) ir a android Studio
file->open
ir hasta la carpeta del proyecto y click en el archivo "android"
4) abrir AVD Manager
del listado de Your Virtual Devices click en el boton verde de play para lanzar ese emulador
5) desde la consola y dentro de la carpeta de la aplicacion creada:
react-native run-android
6) Si todo esta ok deberia aparecer en la pantalla del emulador el siguiente texto de prueba:
Welcome to React Native!
To get started, edit App.js
Double tap R on your keyboard to reload,
Shake or press menu button for dev menu
el cual se encuentra en App.js en la raiz del proyecto
react native 0.57 seteos iniciales
informacion obtenida de
https://facebook.github.io/react-native/docs/getting-started.html
1) instalar chocolatey, un administrador de paquetes para windows:
desde la consola
@"%SystemRoot%\System32\WindowsPowerShell\v1.0\powershell.exe" -NoProfile -InputFormat None -ExecutionPolicy Bypass -Command "iex ((New-Object System.Net.WebClient).DownloadString('https://chocolatey.org/install.ps1'))" && SET "PATH=%PATH%;%ALLUSERSPROFILE%\chocolatey\bin"
2) instalar dependencias necesarias
choco install -y nodejs.install python2 jdk8
3) instalar el react cli (command line interface)
npm install -g react-native-cli
4) instalar android studio
5) al instalar android studio se instalara el ultimo sAndroid dk disponible pero para esta version de react native vamos a necesitar la
Android 8.0 (Oreo)
entonces vamos al SDK Manager
click en la pestana de SDK Platforms
(click en el checkbox inferior-derecha de "show package details")
check en Android 8.0 desplegar y verificar que esten tambien marcadas las opciones
click en "Apply".
6)setear en las variables de entorno android_home con el valor del sdk de android
ANDROID_HOME
usalmente se encuentra en esta direccion:
c:\Users\YOUR_USERNAME\AppData\Local\Android\Sdk
7) crear un nuevo AVD android virtual device
click en el icono de AVD MAnager
click en +new Virtual Device
seleccionar el tab de Phone y click en Next
luego Select the "x86 Images" tab, then look for the Oreo API Level 26, x86_64 ABI image with a Android 8.0 (Google APIs) target.
listo
habra tambien que Install HAXM que seguramente te pedira al momento de hacerle clik en el boton triangular vede de play
https://facebook.github.io/react-native/docs/getting-started.html
1) instalar chocolatey, un administrador de paquetes para windows:
desde la consola
@"%SystemRoot%\System32\WindowsPowerShell\v1.0\powershell.exe" -NoProfile -InputFormat None -ExecutionPolicy Bypass -Command "iex ((New-Object System.Net.WebClient).DownloadString('https://chocolatey.org/install.ps1'))" && SET "PATH=%PATH%;%ALLUSERSPROFILE%\chocolatey\bin"
2) instalar dependencias necesarias
choco install -y nodejs.install python2 jdk8
3) instalar el react cli (command line interface)
npm install -g react-native-cli
4) instalar android studio
5) al instalar android studio se instalara el ultimo sAndroid dk disponible pero para esta version de react native vamos a necesitar la
Android 8.0 (Oreo)
entonces vamos al SDK Manager
click en la pestana de SDK Platforms
(click en el checkbox inferior-derecha de "show package details")
check en Android 8.0 desplegar y verificar que esten tambien marcadas las opciones
- Android SDK Platform 26
- Google APIs Intel x86 Atom_64 System Image
click en "Apply".
6)setear en las variables de entorno android_home con el valor del sdk de android
ANDROID_HOME
usalmente se encuentra en esta direccion:
c:\Users\YOUR_USERNAME\AppData\Local\Android\Sdk
7) crear un nuevo AVD android virtual device
click en el icono de AVD MAnager
click en +new Virtual Device
seleccionar el tab de Phone y click en Next
luego Select the "x86 Images" tab, then look for the Oreo API Level 26, x86_64 ABI image with a Android 8.0 (Google APIs) target.
listo
habra tambien que Install HAXM que seguramente te pedira al momento de hacerle clik en el boton triangular vede de play
ubuntu error cuando ejecutamos php.exe PHP Startup: Unable to load dynamic library '/usr/lib/php/20160303/php_mbstring.dll
PHP Startup: Unable to load dynamic library '/usr/lib/php/20160303/php_mbstring.dll
editar el php.ini
comentar con un punto-y-coma al inicio, la siguiente linea
extension=php_mbstring.dll
;extension=php_mbstring.dll ; commented out
para saber donde se encuentra este archivo:
php -i | grep -i "Loaded Configuration File"
a veces si no se tiene permisos de escritura hay que modificarlo asi
editar el php.ini
comentar con un punto-y-coma al inicio, la siguiente linea
extension=php_mbstring.dll
;extension=php_mbstring.dll ; commented out
para saber donde se encuentra este archivo:
php -i | grep -i "Loaded Configuration File"
a veces si no se tiene permisos de escritura hay que modificarlo asi
sudo chmod 755 /etc/php/7.1/cli/php.ini
sublime3 psr2 plugin
1) Ctrl+shift+p
y buscamos "instALL PACKAGE"
2) luego buscamos "codeFormatter" le damos enter para que se instale
3) vamos a
preferences->package settings->Codeformatter->Settings default
y editar la variable
"php_path": "",
con la ruta donde se tiene instalado el php.exe
esto se puede averiguar tipeando en consola
whereis php
en mi caso es /usr/bin/php7.1
quedaria
"php_path": "/usr/bin/php7.1",
listo!
4) como usarlo?
abrir el archivo que quieras formatear
ctrl+shift+p
tipear "format code" y enter
(para archivos php esta por default seteado para que lo formatee en psr-2)
y buscamos "instALL PACKAGE"
2) luego buscamos "codeFormatter" le damos enter para que se instale
3) vamos a
preferences->package settings->Codeformatter->Settings default
y editar la variable
"php_path": "",
con la ruta donde se tiene instalado el php.exe
esto se puede averiguar tipeando en consola
whereis php
en mi caso es /usr/bin/php7.1
quedaria
"php_path": "/usr/bin/php7.1",
listo!
4) como usarlo?
abrir el archivo que quieras formatear
ctrl+shift+p
tipear "format code" y enter
(para archivos php esta por default seteado para que lo formatee en psr-2)
sublime3 ocultar panel lateral + ver archivo actual en arbol de archivos
ir a
preferences->key bindings
y copiar las sgts sentencias dentro del sublime.keymap-User
// Toggle the Sidebar
{ "keys": ["ctrl+\\"], "command": "toggle_side_bar" },
// BONUS: Reveal current file on the sidebar tree
{ "keys": ["ctrl+shift+r"], "command": "reveal_in_side_bar" },
preferences->key bindings
y copiar las sgts sentencias dentro del sublime.keymap-User
// Toggle the Sidebar
{ "keys": ["ctrl+\\"], "command": "toggle_side_bar" },
// BONUS: Reveal current file on the sidebar tree
{ "keys": ["ctrl+shift+r"], "command": "reveal_in_side_bar" },
curso vue laravel paginacion
1-Modificar el controlador para que en el metodo index(el de listar) se devuelva una respuesta
que contemple las variables necesarias para la paginacion
2-Crear un componente que lea las variables que devuelve el controler y maneje la paginacion
3-Registrar el componente de paginacion en el app.js
CategoriaController.php:
public function index(Request $request)
{
$categorias = Categoria::paginate(3);
$response = [
'pagination' => [
'total' => $categorias->total(),
'per_page' => $categorias->perPage(),
'current_page' => $categorias->currentPage(),
'last_page' => $categorias->lastPage(),
'from' => $categorias->firstItem(),
'to' => $categorias->lastItem()
],
'data' => $categorias
];
return response()->json($response);
}
creamos en resources/js/components/PaginationComponent.vue:
(la parte de html usa el estilo de coreui)
<template>
<nav>
<ul class="pagination">
<li class="page-item">
<a class="page-link" @click.prevent="changePage(pagination.current_page - 1)" :disabled="pagination.current_page <= 1">Ant</a>
</li>
<li v-for="page in pages" class="page-item" :class="isCurrentPage(page) ? 'active' : ''">
<a class="page-link" @click.prevent="changePage(page)">{{ page }}</a>
</li>
<li class="page-item">
<a class="page-link" @click.prevent="changePage(pagination.current_page + 1)" :disabled="pagination.current_page >= pagination.last_page">Sig</a>
</li>
</ul>
</nav>
</template>
<style>
.pagination {
margin-top: 40px;
}
</style>
<script>
export default {
props: ['pagination', 'offset'],
methods: {
isCurrentPage(page) {
return this.pagination.current_page === page;
},
changePage(page) {
if (page > this.pagination.last_page) {
page = this.pagination.last_page;
}
this.pagination.current_page = page;
this.$emit('paginate');
}
},
computed: {
pages() {
let pages = [];
let from = this.pagination.current_page - Math.floor(this.offset / 2);
if (from < 1) {
from = 1;
}
let to = from + this.offset - 1;
if (to > this.pagination.last_page) {
to = this.pagination.last_page;
}
while (from <= to) {
pages.push(from);
from++;
}
return pages;
}
}
}
</script>
en app.js
Vue.component('pagination', require('./components/PaginationComponent.vue'));
ya se puede usar el componente, dentro del componente de categoria que maneja toda la grilla de categorias
<pagination v-if="pagination.last_page > 1" :pagination="pagination" :offset="5" @paginate="fetchRecords()"></pagination>
...
<script>
export default {
data(){
return {
nombre:'',
descripcion:'',
arrayCategorias:[],
modal:0,
tituloModal:'',
accion:'',
errors:[],
categoria_id:0,
pagination: {
'current_page': 1
}
}
},
mounted() {
this.fetchRecords();
},
methods:{
fetchRecords() {
axios.get('/categorias?page=' + this.pagination.current_page)
.then(response => {
//console.log(response);
this.arrayCategorias = response.data.data.data;
this.pagination = response.data.pagination;
})
.catch(error => {
console.log(error.response.data);
});
},
que contemple las variables necesarias para la paginacion
2-Crear un componente que lea las variables que devuelve el controler y maneje la paginacion
3-Registrar el componente de paginacion en el app.js
CategoriaController.php:
public function index(Request $request)
{
$categorias = Categoria::paginate(3);
$response = [
'pagination' => [
'total' => $categorias->total(),
'per_page' => $categorias->perPage(),
'current_page' => $categorias->currentPage(),
'last_page' => $categorias->lastPage(),
'from' => $categorias->firstItem(),
'to' => $categorias->lastItem()
],
'data' => $categorias
];
return response()->json($response);
}
creamos en resources/js/components/PaginationComponent.vue:
(la parte de html usa el estilo de coreui)
<template>
<nav>
<ul class="pagination">
<li class="page-item">
<a class="page-link" @click.prevent="changePage(pagination.current_page - 1)" :disabled="pagination.current_page <= 1">Ant</a>
</li>
<li v-for="page in pages" class="page-item" :class="isCurrentPage(page) ? 'active' : ''">
<a class="page-link" @click.prevent="changePage(page)">{{ page }}</a>
</li>
<li class="page-item">
<a class="page-link" @click.prevent="changePage(pagination.current_page + 1)" :disabled="pagination.current_page >= pagination.last_page">Sig</a>
</li>
</ul>
</nav>
</template>
<style>
.pagination {
margin-top: 40px;
}
</style>
<script>
export default {
props: ['pagination', 'offset'],
methods: {
isCurrentPage(page) {
return this.pagination.current_page === page;
},
changePage(page) {
if (page > this.pagination.last_page) {
page = this.pagination.last_page;
}
this.pagination.current_page = page;
this.$emit('paginate');
}
},
computed: {
pages() {
let pages = [];
let from = this.pagination.current_page - Math.floor(this.offset / 2);
if (from < 1) {
from = 1;
}
let to = from + this.offset - 1;
if (to > this.pagination.last_page) {
to = this.pagination.last_page;
}
while (from <= to) {
pages.push(from);
from++;
}
return pages;
}
}
}
</script>
en app.js
Vue.component('pagination', require('./components/PaginationComponent.vue'));
ya se puede usar el componente, dentro del componente de categoria que maneja toda la grilla de categorias
<pagination v-if="pagination.last_page > 1" :pagination="pagination" :offset="5" @paginate="fetchRecords()"></pagination>
...
<script>
export default {
data(){
return {
nombre:'',
descripcion:'',
arrayCategorias:[],
modal:0,
tituloModal:'',
accion:'',
errors:[],
categoria_id:0,
pagination: {
'current_page': 1
}
}
},
mounted() {
this.fetchRecords();
},
methods:{
fetchRecords() {
axios.get('/categorias?page=' + this.pagination.current_page)
.then(response => {
//console.log(response);
this.arrayCategorias = response.data.data.data;
this.pagination = response.data.pagination;
})
.catch(error => {
console.log(error.response.data);
});
},
curso vue laravel crud
ejemplo CRUD Categoria
creamos un componente para categoria, resources/js/components/CategoriaComponent.vue
que manejara todo el modulo crud de Categoria
en resources/js/app.js
hacemos referencia al componente y definimos el tag "categoria" para referrirnos al componente
Vue.component('categoria', require('./components/CategoriaComponent.vue'));
creamos un componente para categoria, resources/js/components/CategoriaComponent.vue
que manejara todo el modulo crud de Categoria
en resources/js/app.js
hacemos referencia al componente y definimos el tag "categoria" para referrirnos al componente
Vue.component('categoria', require('./components/CategoriaComponent.vue'));
el componente tiene las sgts partes:
template: aqui va todo el html
script: codigo javascript
style: estilos particulares a usarse en este componente
para el CREAR
dentro del template tendremos un boton que abrira una ventana modal con los campos para registrar una nueva categoria
<button type="button" @click="abrirModal('registrar')" class="btn btn-secondary" >
<i class="icon-plus"></i> Nuevo
</button>
y la estructura de la ventana modal
<div class="modal fade" tabindex="-1" :class="{'mostrar':modal}" role="dialog" aria-labelledby="myModalLabel" style="display: none;" aria-hidden="true">
<h4 class="modal-title" v-text="tituloModal"></h4>
<input type="text" v-model="nombre" class="form-control" >
<input type="text" v-model="descripcion" class="form-control" >
<div v-show="errors.length" class="form-group row">
<div class="col-md-12">
<div class="alert alert-danger" role="alert" v-for="error in errors" v-text="error">
</div>
</div>
</div>
<button type="button" class="btn btn-secondary" @click="cerrarModal()">Cerrar</button>
<button type="button" v-if="accion=='guardar'" @click="registrarCategoria()" class="btn btn-primary">Guardar</button>
entonces en la seccion de script
export default {
data(){
return {
nombre:'',
descripcion:'',
modal:0,
tituloModal:'',
accion:'',
errors:[]
}
},
methods:{
registrarCategoria(){
if(!this.validarCategoria()){
return;
}
let me=this;
axios.post('/categorias/registrar',{
'nombre':me.nombre,
'descripcion':me.descripcion
}).then(function (response) {
// handle success
me.cerrarModal();
me.listarCategorias();
})
.catch(function (error) {
// handle error
console.log(error);
});
},
abrirModal(accion,data=[]){
switch(accion){
case 'registrar':
{
this.modal = 1;
this.nombre = '';
this.descripcion = '';
this.tituloModal = 'Registrar nueva categoria';
this.accion='guardar';
//console.log('registrar');
break;
}
}
donde:
modal:0, // indica si se muestra (1) o no (0) la ventana modal
tituloModal:'', //titulo de la ventana modal, es variable porque se usara el mismo para actualizar
accion:'', //accion actual, registrar o actualizar
errors:[] // array con los mensajes de error
para ACTUALIZAR
tenemos un icono de editar por cada registro del listado
<tr v-for="categoria in arrayCategorias.data" :key="categoria.id">
<td>
<button type="button" class="btn btn-warning btn-sm"
@click="abrirModal('actualizar',categoria)" >
<i class="icon-pencil"></i>
</button>
en este caso le enviamos los datos de categoria actual para llenar los campos del formulario de la ventana modal.
y en la ventana modal cuando se abra el boton dira actualizar y llamara a actualizarCAtegoria
<button type="button" v-if="accion=='actualizar'" @click="actualizarCategoria()"class="btn btn-primary">Actualizar</button>
abrirModal(accion,data=[]){
switch(accion){
case 'actualizar':
{
this.modal = 1;
this.nombre = data['nombre'];
this.descripcion = data['descripcion'];
this.tituloModal = 'Actualizar categoria';
this.categoria_id = data['id'];
this.accion='actualizar';
//console.log('registrar');
break;
}
}
}
actualizarCategoria(){
if(!this.validarCategoria()){
return;
}
let me=this;
axios.put('/categorias/actualizar',{
'nombre':me.nombre,
'descripcion':me.descripcion,
'id':me.categoria_id,
}).then(function (response) {
// handle success
me.cerrarModal();
me.listarCategorias();
})
.catch(function (error) {
// handle error
console.log(error);
});
},
en nuestro archivo de rutas routes/web.php
tenemos
Route::get('/categorias', ['uses'=>'CategoriaController@index']);
Route::post('/categorias/registrar', ['uses'=>'CategoriaController@store']);
Route::put('/categorias/actualizar', ['uses'=>'CategoriaController@update']);
entonces, el problema es que si desde la url apuntamos a esas rutas
por ejemplo http://localhost:8000/categorias
escupira en el browser en forma de json la categorias de la tabla.
entonces le vamos a agregar una minima seguridad, haciendo que cada uno de los metodos del controller solo respondan si la peticion fue hecha a traves de una llamada ajax. de lo contrario se redirigira a la pagina raiz
en la primera linea del cuerpo de cada metodo agregar:
if(!$request->ajax()) return redirect("/");
en nuestro archivo de rutas routes/web.php
tenemos
Route::get('/categorias', ['uses'=>'CategoriaController@index']);
Route::post('/categorias/registrar', ['uses'=>'CategoriaController@store']);
Route::put('/categorias/actualizar', ['uses'=>'CategoriaController@update']);
entonces, el problema es que si desde la url apuntamos a esas rutas
por ejemplo http://localhost:8000/categorias
escupira en el browser en forma de json la categorias de la tabla.
entonces le vamos a agregar una minima seguridad, haciendo que cada uno de los metodos del controller solo respondan si la peticion fue hecha a traves de una llamada ajax. de lo contrario se redirigira a la pagina raiz
en la primera linea del cuerpo de cada metodo agregar:
if(!$request->ajax()) return redirect("/");
como saber la version de laravel de tu proyecto
por consola y desde la raiz de tu proyecto
php artisan --version
curl ubuntu
si tienes un archivo que haga llamadas curl
para ejecutarlo
php -f miarchivo.php
si te sale
PHP Fatal error: Call to undefined function curl_init()
quiere decir que no está instalado el modulo de curl, esto tambien se puede comprobar
<?php var_dump(extension_loaded('curl')); ?>
y si da false,
sudo apt-get install php7.1-curl
para versiones de php 7.1.x
para ejecutarlo
php -f miarchivo.php
si te sale
PHP Fatal error: Call to undefined function curl_init()
quiere decir que no está instalado el modulo de curl, esto tambien se puede comprobar
<?php var_dump(extension_loaded('curl')); ?>
y si da false,
sudo apt-get install php7.1-curl
para versiones de php 7.1.x
curso vue.js laravel conceptos
es un framework javascript progresivo para crear interfaces de usuario pudiendo agregarsela a la parte de tu aplicacion que necesites que sea mas intuitiva e interactiva.diviendo una pagina web en componentes reutilizables (con su propio html, css y javascript).
vue.js es reactivo es decir que si si la data se modifica el front que la muestra tambien(data binding)
https://vuejs.org/v2/guide/installation.html
descargamos la version de desarrollo y la de produccion(es la de desarrollo minificada y sin comentarios) haciendo clik sobre ambas opciones,
y la guardamos dentro de una carpeta de nuestra aplicacion (llamada por ejemplo js)
https://getbootstrap.com/docs/4.1/getting-started/introduction/
copiamos de esta pagina la direccion cdn de bootstrap
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.2/css/bootstrap.min.css" integrity="sha384-Smlep5jCw/wG7hdkwQ/Z5nLIefveQRIY9nfy6xoR1uRYBtpZgI6339F5dgvm/e9B" crossorigin="anonymous">
y lo pegamos en el head de nuestro proyecto.
vue.js es reactivo es decir que si si la data se modifica el front que la muestra tambien(data binding)
https://vuejs.org/v2/guide/installation.html
descargamos la version de desarrollo y la de produccion(es la de desarrollo minificada y sin comentarios) haciendo clik sobre ambas opciones,
y la guardamos dentro de una carpeta de nuestra aplicacion (llamada por ejemplo js)
https://getbootstrap.com/docs/4.1/getting-started/introduction/
copiamos de esta pagina la direccion cdn de bootstrap
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.2/css/bootstrap.min.css" integrity="sha384-Smlep5jCw/wG7hdkwQ/Z5nLIefveQRIY9nfy6xoR1uRYBtpZgI6339F5dgvm/e9B" crossorigin="anonymous">
y lo pegamos en el head de nuestro proyecto.
curso vue.js laravel crear proyecto
crear un db a traves de phpmyadmin
http://localhost/phpmyadmin/
la llamaremos dbsistemalaravel
instalar laravel
composer global require "laravel/installer"
vamos a la ruta_xampp/htdocs
y por la consola creamos el proyecto asi
laravel new sislaravel
luego abrimos el proyecto(carpeta) en nuestro editor
duplicamos el archivo .env.example y lo lllamamos .env
luego generamos una key de encriptacion a traves de la consola
php artisan key:generate
luego podemos levantar el servidor interno
php artisan serve
y acceder a nuestra aplicacion a traves de la sgt url
http://127.0.0.1:8000/
http://localhost/phpmyadmin/
la llamaremos dbsistemalaravel
instalar laravel
composer global require "laravel/installer"
vamos a la ruta_xampp/htdocs
y por la consola creamos el proyecto asi
laravel new sislaravel
luego abrimos el proyecto(carpeta) en nuestro editor
duplicamos el archivo .env.example y lo lllamamos .env
luego generamos una key de encriptacion a traves de la consola
php artisan key:generate
luego podemos levantar el servidor interno
php artisan serve
y acceder a nuestra aplicacion a traves de la sgt url
http://127.0.0.1:8000/
curso node llamar a un service web api
primero vamos a instalar yargs
y setear que reciba (esta vez sin un comando de por medio) el argumento
de la direccion de la que se quiere saber su clima
const argv=require('yargs').options(
{
direccion:{
alias:'d',
demand:true,
desc: 'direccion a traer el clima'
}
}).
argv;
console.log(argv.direccion);
entonces si llamamos
node app -d "buenos aires argentina"
obtendremos
buenos aires argentina
vamos a instalar ahora un paquete para poder hacer llamadas a apis externas,
en este caso usaremos Axios (tambien puede ser request)
npm install axios --save
recordar que ponemos el --save para que se registre el paquete en el package.json como un dependencia, de lo contrario, se bajara la libreria sin registrarse la dependencia.
si se quiere instalar una version en especifico simplemente la escribimos antecediendole una arroba:
npm installa axios@0.18.0 --save
ahora ya podemos utilizarlo para llamar al webservice de google de geocoding
const axios=require('axios');
const urlEncoded = encodeURIComponent(argv.direccion);//para que convierta espacios
const apiKey = "AIzaSyBlRKjSjinm50447yd_qWAjvzojhWND7Ip-w";
axios.get(`https://maps.googleapis.com/maps/api/geocode/json?address=${urlEncoded}&key=${apiKey}`)
.then(function (response) {
console.log(JSON.stringify(response.data));
})
.catch(function (error) {
console.log(error);
});
usamos response.data
para que por consola nos muestre solo los datos de la data de geocoding
y JSON.stringify(response.data)
para que nos muestre los datos de los objetos / arrays que trae Data sino no los podremos ver.
por consola los datos apareceran uno al lado del otro si queremos que se vean en distintas lineas
y con margenes usamos
JSON.stringify(response.data,undefined,2));
la respuesta sera algo asi
{
"results": [
{
"address_components": [
{
"long_name": "Buenos Aires",
"short_name": "CABA",
"types": [
"locality",
"political"
]
},
{
"long_name": "Buenos Aires",
"short_name": "CABA",
"types": [
"administrative_area_level_1",
"political"
]
},
{
"long_name": "Argentina",
"short_name": "AR",
"types": [
"country",
"political"
]
}
],
"formatted_address": "Buenos Aires, Argentina",
"geometry": {
"bounds": {
"northeast": {
"lat": -34.5265464,
"lng": -58.33514470000001
},
"southwest": {
"lat": -34.7051011,
"lng": -58.5314522
}
},
"location": {
"lat": -34.6036844,
"lng": -58.3815591
},
"location_type": "APPROXIMATE",
"viewport": {
"northeast": {
"lat": -34.5265464,
"lng": -58.33514470000001
},
"southwest": {
"lat": -34.7051011,
"lng": -58.5314522
}
}
},
"place_id": "ChIJvQz5TjvKvJURh47oiC6Bs6A",
"types": [
"locality",
"political"
]
}
],
"status": "OK"
}
entonces..si quisieramos imprimir solo la direccion formateada, la latitud y la longitud hariamos esto:
let results = response.data.results[0];
let formatted_address = results.formatted_address;
let lat = results.geometry.location.lat;
let lng = results.geometry.location.lng;
console.log(`Direccion: ${formatted_address}`);
console.log(`Longitud: ${lng}`);
console.log(`Latitud: ${lat}`);
///////////////////////// refactorizando el codigo//////////////////////////////////
vamos a crear una funcion getLugar para que nos devuelva un objeto con las propiedades
direccion,latitud y longitud. Y lo escribiremos en un archivo aparte (lugar/lugar.app) dentro de un carpeta llamada lugar.
lugar.js:
const axios=require('axios');
const getLugar = async (direccion) => {
let addressEncoded = encodeURI(direccion);
let apiKey = "AIzaSyBlRKjSjinm507yd_qWAjvzojhWND7Ip-w";
let resp = await axios.get(`https://maps.googleapis.com/maps/api/geocode/json?address=${addressEncoded}&key=${apiKey}`);
if(resp.data.status === "ZERO_RESULTS"){
throw new Error("No se encontraron resultados");
}
let results = resp.data.results[0];
return {
direccion: results.formatted_address,
longitud:results.geometry.location.lng,
latitud:results.geometry.location.lat
}
}
module.exports = {
getLugar
}
y en app.js
const argv=require('yargs').options(
{
direccion:{
alias:'d',
demand:true,
desc: 'direccion a traer el clima'
}
}).
argv;
const { getLugar } = require('./lugar/lugar.js');
getLugar(argv.direccion)
.then(resp=>{
console.log(resp)
}).catch(e=>console.log(e));
y setear que reciba (esta vez sin un comando de por medio) el argumento
de la direccion de la que se quiere saber su clima
const argv=require('yargs').options(
{
direccion:{
alias:'d',
demand:true,
desc: 'direccion a traer el clima'
}
}).
argv;
console.log(argv.direccion);
entonces si llamamos
node app -d "buenos aires argentina"
obtendremos
buenos aires argentina
vamos a instalar ahora un paquete para poder hacer llamadas a apis externas,
en este caso usaremos Axios (tambien puede ser request)
npm install axios --save
recordar que ponemos el --save para que se registre el paquete en el package.json como un dependencia, de lo contrario, se bajara la libreria sin registrarse la dependencia.
si se quiere instalar una version en especifico simplemente la escribimos antecediendole una arroba:
npm installa axios@0.18.0 --save
ahora ya podemos utilizarlo para llamar al webservice de google de geocoding
const axios=require('axios');
const urlEncoded = encodeURIComponent(argv.direccion);//para que convierta espacios
const apiKey = "AIzaSyBlRKjSjinm50447yd_qWAjvzojhWND7Ip-w";
axios.get(`https://maps.googleapis.com/maps/api/geocode/json?address=${urlEncoded}&key=${apiKey}`)
.then(function (response) {
console.log(JSON.stringify(response.data));
})
.catch(function (error) {
console.log(error);
});
usamos response.data
para que por consola nos muestre solo los datos de la data de geocoding
y JSON.stringify(response.data)
para que nos muestre los datos de los objetos / arrays que trae Data sino no los podremos ver.
por consola los datos apareceran uno al lado del otro si queremos que se vean en distintas lineas
y con margenes usamos
JSON.stringify(response.data,undefined,2));
la respuesta sera algo asi
{
"results": [
{
"address_components": [
{
"long_name": "Buenos Aires",
"short_name": "CABA",
"types": [
"locality",
"political"
]
},
{
"long_name": "Buenos Aires",
"short_name": "CABA",
"types": [
"administrative_area_level_1",
"political"
]
},
{
"long_name": "Argentina",
"short_name": "AR",
"types": [
"country",
"political"
]
}
],
"formatted_address": "Buenos Aires, Argentina",
"geometry": {
"bounds": {
"northeast": {
"lat": -34.5265464,
"lng": -58.33514470000001
},
"southwest": {
"lat": -34.7051011,
"lng": -58.5314522
}
},
"location": {
"lat": -34.6036844,
"lng": -58.3815591
},
"location_type": "APPROXIMATE",
"viewport": {
"northeast": {
"lat": -34.5265464,
"lng": -58.33514470000001
},
"southwest": {
"lat": -34.7051011,
"lng": -58.5314522
}
}
},
"place_id": "ChIJvQz5TjvKvJURh47oiC6Bs6A",
"types": [
"locality",
"political"
]
}
],
"status": "OK"
}
entonces..si quisieramos imprimir solo la direccion formateada, la latitud y la longitud hariamos esto:
let results = response.data.results[0];
let formatted_address = results.formatted_address;
let lat = results.geometry.location.lat;
let lng = results.geometry.location.lng;
console.log(`Direccion: ${formatted_address}`);
console.log(`Longitud: ${lng}`);
console.log(`Latitud: ${lat}`);
///////////////////////// refactorizando el codigo//////////////////////////////////
vamos a crear una funcion getLugar para que nos devuelva un objeto con las propiedades
direccion,latitud y longitud. Y lo escribiremos en un archivo aparte (lugar/lugar.app) dentro de un carpeta llamada lugar.
lugar.js:
const axios=require('axios');
const getLugar = async (direccion) => {
let addressEncoded = encodeURI(direccion);
let apiKey = "AIzaSyBlRKjSjinm507yd_qWAjvzojhWND7Ip-w";
let resp = await axios.get(`https://maps.googleapis.com/maps/api/geocode/json?address=${addressEncoded}&key=${apiKey}`);
if(resp.data.status === "ZERO_RESULTS"){
throw new Error("No se encontraron resultados");
}
let results = resp.data.results[0];
return {
direccion: results.formatted_address,
longitud:results.geometry.location.lng,
latitud:results.geometry.location.lat
}
}
module.exports = {
getLugar
}
y en app.js
const argv=require('yargs').options(
{
direccion:{
alias:'d',
demand:true,
desc: 'direccion a traer el clima'
}
}).
argv;
const { getLugar } = require('./lugar/lugar.js');
getLugar(argv.direccion)
.then(resp=>{
console.log(resp)
}).catch(e=>console.log(e));
curso node crear release del proyecto
vamos a crear un tag desde la carpeta en la consola
git tag -a v1.0 -m "Primera version"
listamos los tags
git tag
veremos que hay uno solo
v1.0
y luego pusheamos
git push --tags
luego vamos a nuestra pagina de github y hacemos click en la cabecera que dice "release"
vamos a la pestaña de Tags y ahi clickeamos en "crear release"
le ponemos un titulo, una descripcion y click en el boton de publicar.
nos quedaria algo asi
git tag -a v1.0 -m "Primera version"
listamos los tags
git tag
veremos que hay uno solo
v1.0
y luego pusheamos
git push --tags
luego vamos a nuestra pagina de github y hacemos click en la cabecera que dice "release"
vamos a la pestaña de Tags y ahi clickeamos en "crear release"
le ponemos un titulo, una descripcion y click en el boton de publicar.
nos quedaria algo asi
un Release es un Tag con una descripcion.
entonces desde aqui se puede hacer click para descargar facilmente todo el codigo fuente de la aplicacion
wordress creando un plugin para wordpress
la razon principal para escribir un plugin es separar tu codigo del codigo core de wordpress.
Si algo sale mal el resto del sitio seguira , funcionando.
Una alternativa para modificar las funciones de wordpress es editar el archivo
wp-includes/functions.php o functions.php que es parte de un theme. Sin embargo esto no es recomendable debido a las constantes actualizaciones de wordpress que borraran las modificaciones que le hagas a su archivo functions.php
Los plugind interactuan con el core de wordpress atraves de hooks,
existen 2 tipos de hooks:
1-action hooks , para agregar y/o eliminar funciones
2-filter hooks, para modificar datos producidos por funciones
para crear y activar un plugin nuestro, creamos el archivo php dentro de la carpeta wp-content/plugins
luego en el admin de wordpress, vamos al menu de PLugins, lo ubicamos y activamos.
Ejemplo de action hook, para agregar un bloque de texto al final del footer y lo saca si es domingo (Sunday)
<?php
/*
Plugin Name: Add Text To Footer
Description: Example Plugin Action Hook
*/
// Hook the 'wp_footer' action hook, add the function named 'mfp_Add_Text' to it
add_action("wp_footer", "mfp_Add_Text");
// Hook the 'wp_head' action, run the function named 'mfp_Remove_Text()'
add_action("wp_head", "mfp_Remove_Text");
// Define 'mfp_Add_Text'
function mfp_Add_Text()
{
echo "<p style='color: black;'>".date("l")."Despues de que el Footer es cargado, mi texto es agrega.do! </p>";
}
// Define the function named 'mfp_Remove_Text()' to remove our previous function from the 'wp_footer' action
function mfp_Remove_Text()
{
if (date("l") === "Sunday") {
// Target the 'wp_footer' action, remove the 'mfp_Add_Text' function from it
remove_action("wp_footer", "mfp_Add_Text");
}
}
Ejemplo de filter Hook, que reemplaza los espacios en blanco del contenido de un post por asteriscos
<?php
/*
Plugin Name: Replace text space in content post
Description: Example PLugin Filter hook
*/
// Hook the 'the_content' filter hook (content of any post), run the function named 'mfp_Fix_Text_Spacing'
add_filter("the_content", "mfp_Fix_Text_Spacing");
// Automatically correct double spaces from any post
function mfp_Fix_Text_Spacing($the_Post)
{
$the_New_Post = str_replace(" ", "*", $the_Post);
return $the_New_Post;
}
Si algo sale mal el resto del sitio seguira , funcionando.
Una alternativa para modificar las funciones de wordpress es editar el archivo
wp-includes/functions.php o functions.php que es parte de un theme. Sin embargo esto no es recomendable debido a las constantes actualizaciones de wordpress que borraran las modificaciones que le hagas a su archivo functions.php
Los plugind interactuan con el core de wordpress atraves de hooks,
existen 2 tipos de hooks:
1-action hooks , para agregar y/o eliminar funciones
2-filter hooks, para modificar datos producidos por funciones
para crear y activar un plugin nuestro, creamos el archivo php dentro de la carpeta wp-content/plugins
luego en el admin de wordpress, vamos al menu de PLugins, lo ubicamos y activamos.
Ejemplo de action hook, para agregar un bloque de texto al final del footer y lo saca si es domingo (Sunday)
<?php
/*
Plugin Name: Add Text To Footer
Description: Example Plugin Action Hook
*/
// Hook the 'wp_footer' action hook, add the function named 'mfp_Add_Text' to it
add_action("wp_footer", "mfp_Add_Text");
// Hook the 'wp_head' action, run the function named 'mfp_Remove_Text()'
add_action("wp_head", "mfp_Remove_Text");
// Define 'mfp_Add_Text'
function mfp_Add_Text()
{
echo "<p style='color: black;'>".date("l")."Despues de que el Footer es cargado, mi texto es agrega.do! </p>";
}
// Define the function named 'mfp_Remove_Text()' to remove our previous function from the 'wp_footer' action
function mfp_Remove_Text()
{
if (date("l") === "Sunday") {
// Target the 'wp_footer' action, remove the 'mfp_Add_Text' function from it
remove_action("wp_footer", "mfp_Add_Text");
}
}
Ejemplo de filter Hook, que reemplaza los espacios en blanco del contenido de un post por asteriscos
<?php
/*
Plugin Name: Replace text space in content post
Description: Example PLugin Filter hook
*/
// Hook the 'the_content' filter hook (content of any post), run the function named 'mfp_Fix_Text_Spacing'
add_filter("the_content", "mfp_Fix_Text_Spacing");
// Automatically correct double spaces from any post
function mfp_Fix_Text_Spacing($the_Post)
{
$the_New_Post = str_replace(" ", "*", $the_Post);
return $the_New_Post;
}
wordpress programando en wordpress
worpress tiene 3 componentes principales:
el core, themes y plugins
core: contiene todo el codigo que lo hace funcionar como un CMS
This includes desde the admin backend hasta functions like scheduling posts, password strength checking, lae creation of users and asi. is responsible for the backend of a website and how it operates.
themes: are responsible for the front-end and how website’s look and feel. You might want to install and activate pre-built themes or break out of the box completely and go your own way with custom designs.
plugins: proveen funcionalidad extra a wordpress. To make this happen, a plugin may modify the backend and/or the front-end of a website. A plugin that adds a Tweet button for Twitter is a good example. It would probably create a new settings page in the backend admin menu where you could set up some default options for a user’s tweet and it would also add itself to the front-end of a website, most likely displaying under a post.
themes,plugins, rest apis, core
You can connect to any website and ask it for your latest five posts. But you can do a lot more than that: you can delete users, create users, edit categories and more (which you need to authenticate yourself, of course). This means you can use WordPress as a repository of information and build the front-end and/or the backend using a different system altogether.
el core, themes y plugins
core: contiene todo el codigo que lo hace funcionar como un CMS
This includes desde the admin backend hasta functions like scheduling posts, password strength checking, lae creation of users and asi. is responsible for the backend of a website and how it operates.
themes: are responsible for the front-end and how website’s look and feel. You might want to install and activate pre-built themes or break out of the box completely and go your own way with custom designs.
plugins: proveen funcionalidad extra a wordpress. To make this happen, a plugin may modify the backend and/or the front-end of a website. A plugin that adds a Tweet button for Twitter is a good example. It would probably create a new settings page in the backend admin menu where you could set up some default options for a user’s tweet and it would also add itself to the front-end of a website, most likely displaying under a post.
areas de desarrollo:
themes,plugins, rest apis, core
Plugins
plugins are la esencia de WordPress, transforming it into everything from a forum to a social network, eCommerce platforms and much more with the push of a button. Plugins give you total control over all aspects of the WordPress system, allowing you to modify anything you want.
The REST API is relatively new and allows you to create true applications based on WordPress. This includes iPhone and Android apps and all sorts of crazy things like TV apps even, if you know some other programming languages.You can connect to any website and ask it for your latest five posts. But you can do a lot more than that: you can delete users, create users, edit categories and more (which you need to authenticate yourself, of course). This means you can use WordPress as a repository of information and build the front-end and/or the backend using a different system altogether.
Suscribirse a:
Entradas (Atom)
linux ubuntu mint actualizar chrome
desde una terminal: $ sudo apt update $ sudo apt install google-chrome-stable
-
por consola y desde la raiz de tu proyecto php artisan --version
-
en nuestro proyecto creamos una carpeta llamada donde estaran todas nuestras clases, por ejemplo una llamada: MiApp adentro de esta irian b...
-
Integridad al nivel de la base de datos Oracle Oracle valida la integridad de la base de datos y presenta los siguientes mensajes de erro...