¿Cómo crear una RED SOCIAL?

Experiencias, ideas y materiales para llevar adelante tu próximo proyecto de creación de una red social

Community Manager

Compartiendo experiencias del cambiante y movido mundo del Community Manager

WordPress

Compartiendo experiencias sobre la plataforma CMS más importante del mundo

BuddyPress

El increíble y fabuloso plugin de WordPress para crear redes sociales verticales

lunes, 22 de septiembre de 2014

[enlace recomendado] 4 plugins para acciones masivas en WordPress

[enlace recomendado] Cómo poner tu WordPress en modo mantenimiento

viernes, 19 de septiembre de 2014

Renovación de dominios en Argentina

¿Cómo renovar un dominio cuando recibimos un mensaje como el siguiente?



1) Ingresar a Nic.ar






2) Seleccionar la opción para renovar el dominio:



3) Confirmar la operación y el costo



4) Confirmar los datos de facturación


5) Seleccionar el medio de pago




6) Completar los datos del titular

En mi caso utilicé tarjeta de crédito, porque la opción de Pagomiscuentas no aparecía en el home banking. 
Aparecerá el siguiente mensaje:




7) Esperar que se confirme el pago

Mientras tanto aparecerá como abierto:




8) Trámite finalizado

Una vez terminado el trámite, les debe aparecer la nueva fecha de vencimiento:



Ye deberían recibir un mensaje por correo como este:


lunes, 15 de septiembre de 2014

Publicar en WordPress desde Microsoft Access via XMLRCP Parte 6

Continuando con la prueba de conexión entre el mundo de Microsoft Access y WordPress, llegamos al artículo número 6 en donde vamos ahora a realizar un ejemplo completo para unir lo que fuimos investigando en los 5 artículos anteriores de XMLRCP, que recomiendo que leas antes de seguir:
¿En qué consistirá nuestro ejemplo completo?

Lo que buscamos al final del camino es haber creado en WordPress un post personalizado con campos personalizados y un archivo asociado.



Para ello desde MS Access, tendremos un formulario que nos pide tres datos y luego nos indica la URL del post creado, tal como se ve en la siguiente imagen:




Código - Principal

En esta primera parte del código incorporamos la lógica, en donde primero subimos el archivo, y luego el post asociado a ese archivo:

Function CargarDocumentoConMetaDataEnWordPress( _
    Cliente As String, Certificado As String, _
    ArchivoConPath As String, Archivo As String) As String

    Dim CodigoDocumento As String
    Dim CodigoProceso As String
    
    ' Subo un archivo a la librería multimedia de WordPress y obtengo el código publicado
    CodigoDocumento = PublicarMedioEnWordPress(Archivo, ArchivoConPath, "application/pdf")
    
    If CodigoDocumento <> "-1" Then
        ' Subo cun ítem de custom post type, asociando el archivo subido
        CodigoProceso = PublicarEnWordPress(CodigoDocumento, Certificado, Cliente)
        
        If CodigoProceso <> "-1" Then
            ' URL en donde se cargó el post type
            CargarDocumentoConMetaDataEnWordPress = "http://blabla.com/?p=" & CodigoProceso
        Else
            MsgBox "Ocurrió un error al intentar subir un post type"
        End If
    
    Else
        MsgBox "Ocurrió un error al intentar subir un documento"
    End If
    
End Function


Código - Publicación de Imagen / Archivo

Hay algunos cambios resaltados respecto a artículos anteriores, que tienen que ver con el cambio de API a wp y con el análisis del XML devuelto como resultado.

Function PublicarMedioEnWordPress(ArchivoNombre As String, ArchivoConCamino As String, ArchivoTipo As String) As String
 
    ' Datos de Autenticación
    CargarConstantes
    txtURL = SITIO
    txtUserName = USUARIO
    txtPassword = PASSWORD
    
    ' Datos del Medio
    txtArchivo = ArchivoNombre
    txtTipo = ArchivoTipo
    Dim txtArchivoConPath As String
    txtArchivoConPath = ArchivoConCamino
      
    ' ServerXMLHTTP
    Dim objSvrHTTP As ServerXMLHTTP
    Dim strT As String
    Set objSvrHTTP = New ServerXMLHTTP
  
    ' Autenticación
    objSvrHTTP.Open "POST", txtURL, False, CStr(txtUsuario), CStr(txtPassword)
    objSvrHTTP.setRequestHeader "Accept", "application/xml"
    objSvrHTTP.setRequestHeader "Content-Type", "application/xml"

    strT = strT & "<methodCall>"
    
    ' Acción
    strT = strT & "<methodName>wp.uploadFile</methodName>"
    
    ' General
    strT = strT & "<params>"
    strT = strT & "<param><value><string>0</string></value></param>"
    strT = strT & "<param><value>" & txtUserName & "</value></param>"
    strT = strT & "<param><value><string>" & txtPassword & "</string></value></param>"
    strT = strT & "<param>"
    
    strT = strT & "<struct>"
    
    ' Nombre, Tipo e Imagen
    strT = strT & "<member><name>name</name><value><![CDATA[" & txtArchivo & "]]></value></member>"
    strT = strT & "<member><name>type</name><value><![CDATA[" & txtTipo & "]]></value></member>"
    strT = strT & "<member><name>bits</name><value><base64>" & EncodeFile(txtArchivoConPath) & "</base64></value></member>"
    
    strT = strT & "</struct>"
    strT = strT & "</param>"
    
    strT = strT & "</params>"
    strT = strT & "</methodCall>"

   
    ' Publicación
    objSvrHTTP.send strT

    ' Debug
    Debug.Print objSvrHTTP.responseText
    'MsgBox objSvrHTTP.responseText
    PublicarMedioEnWordPress = resultado(objSvrHTTP.responseText, "MEDIA")

End Function

Public Function EncodeFile(strPicPath As String) As String
    Const adTypeBinary = 1          ' Binary file is encoded

    ' Variables for encoding
    Dim objXML
    Dim objDocElem

    ' Variable for reading binary picture
    Dim objStream

    ' Open data stream from picture
    Set objStream = CreateObject("ADODB.Stream")
    objStream.Type = adTypeBinary
    objStream.Open
    objStream.LoadFromFile (strPicPath)

    ' Create XML Document object and root node
    ' that will contain the data
    Set objXML = CreateObject("MSXml2.DOMDocument")
    Set objDocElem = objXML.createElement("Base64Data")
    objDocElem.DataType = "bin.base64"

    ' Set binary value
    objDocElem.nodeTypedValue = objStream.Read()

    ' Get base64 value
    EncodeFile = objDocElem.Text
    'EncodeFile = Replace(objDocElem.Text, vbLf, "")

    ' Clean all
    Set objXML = Nothing
    Set objDocElem = Nothing
    Set objStream = Nothing

End Function


Código - Análisis de la respuesta

Esto es nuevo respecto a artículos anteriores y sirve para analizar el XML recibido como respuesta con el fin de encontrar el código interno que WordPress asignó a la imagen o post creado:

Function resultado(strXML, tipo As String) As String

    Dim error As String
    Dim hayError As Boolean
    error = ""
    hayError = False
    
    Set xmlDoc = CreateObject("MSXML2.DOMDocument")
    xmlDoc.loadXML strXML

    ' Busco errores
    Set elements = xmlDoc.getElementsByTagName("fault")
    For Each el In elements
        error = error & el.Text
        hayError = True
    Next
    
    ' Si no hay errores
    If Not hayError Then
        
        ' POST o MEDIA?
        Dim tipoXML As String
        If tipo = "POST" Then
            tipoXML = "params"
        Else
            tipoXML = "string"
        End If
        
        Set elements = xmlDoc.getElementsByTagName(tipoXML)
            
        ' Obtengo el código generado
        resultado = elements(0).Text
    
    ' Si hay errores
    Else
        MsgBox error
        resultado = "-1"
    End If
        
    'MsgBox resultado

End Function


Código - Publicación de Custom Post Type

Y finalmente nuestra función para publicar el custom post type, con pocos cambios respecto a artículos anteriores:

Function PublicarEnWordPress(CodigoArchivo As String, NumeroDocumento As String, CodigoCliente As String) As String
 
    ' Datos de Autenticación
    CargarConstantes
    txtURL = SITIO
    txtUserName = USUARIO
    txtPassword = PASSWORD
    
    ' Datos del Post
    txtTitulo = CodigoCliente & " - " & NumeroDocumento
    txtContenido = "Este es un custom post de ejemplo publicado desde Microsoft Access"
    Dim txtCategorias(1) As String
    txtCategorias(1) = "Uncategorized"
    'txtImagen = "64"
    txtTipoContenido = "proceso"
    txtCliente = CodigoCliente
    txtNumeroCertificado = NumeroDocumento
    txtDocumento = CodigoArchivo
      
    ' ServerXMLHTTP
    Dim objSvrHTTP As ServerXMLHTTP
    Dim strT As String
    Set objSvrHTTP = New ServerXMLHTTP
  
    ' Autenticación
    objSvrHTTP.Open "POST", txtURL, False, CStr(txtUsuario), CStr(txtPassword)
    objSvrHTTP.setRequestHeader "Accept", "application/xml"
    objSvrHTTP.setRequestHeader "Content-Type", "application/xml"

    strT = strT & "<methodCall>"
    
    ' Acción
    strT = strT & "<methodName>wp.newPost</methodName>"
    
    ' General
    strT = strT & "<params>"
    strT = strT & "<param><value><string>0</string></value></param>"
    strT = strT & "<param><value>" & txtUserName & "</value></param>"
    strT = strT & "<param><value><string>" & txtPassword & "</string></value></param>"
    strT = strT & "<param>"
    
    strT = strT & "<struct>"
    
    ' Categorías
    strT = strT & "<member><name>categories</name><value><array>"
    strT = strT & "<data>"
    For i = 1 To UBound(txtCategorias)
        strT = strT & "<value>" & txtCategorias(i) & "</value>"
    Next i
    strT = strT & "</data>"
    strT = strT & "</array></value></member>"
    
    ' Título, contenido y fecha
    strT = strT & "<member><name>post_content</name><value><![CDATA[" & txtContenido & "]]></value></member>"
    strT = strT & "<member><name>post_title</name><value>" & txtTitulo & "</value></member>"
    strT = strT & "<member><name>dateCreated</name><value><dateTime.iso8601>" & Format(Now(), "yyyyMMdd") & "T" & Format(Now(), "hh:mm:ss") & "</dateTime.iso8601></value></member>"
    
    ' Imagen destacada
    ' strT = strT & "<member><name>post_thumbnail</name><value><![CDATA[" & txtImagen & "]]></value></member>"
    
    ' Tipo de contenido
    strT = strT & "<member><name>post_type</name><value>" & txtTipoContenido & "</value></member>"
    
    ' Campos personalizados
    strT = strT & "<member><name>custom_fields</name><value><array><data><value>"
    
    strT = strT & "<struct>"
    strT = strT & "<member><name>key</name><value>cliente</value></member>"
    strT = strT & "<member><name>value</name><value>" & txtCliente & "</value></member>"
    strT = strT & "</struct>"
    
    strT = strT & "<struct>"
    strT = strT & "<member><name>key</name><value>numero_de_certificado</value></member>"
    strT = strT & "<member><name>value</name><value>" & txtNumeroCertificado & "</value></member>"
    strT = strT & "</struct>"
    
    strT = strT & "<struct>"
    strT = strT & "<member><name>key</name><value>documento</value></member>"
    strT = strT & "<member><name>value</name><value>" & txtDocumento & "</value></member>"
    strT = strT & "</struct>"
    
    strT = strT & "</value></data></array></value></member>"
    
    ' Tipo de publicación
    strT = strT & "<member><name>post_status</name><value>publish</value></member>"
    
    strT = strT & "</struct>"
    strT = strT & "</param>"
    strT = strT & "</params>"
    strT = strT & "</methodCall>"
    
    ' Publicación
    objSvrHTTP.send strT
    
    ' Debug
    Debug.Print objSvrHTTP.responseText
    'MsgBox objSvrHTTP.responseText
    PublicarEnWordPress = resultado(objSvrHTTP.responseText, "POST")

End Function


Cambios al sitio en WordPress

Un último detalle. Hemos creado un pequeño plugin en el sitio WordPress para que se puedan visualizar nuestros campos personalizados, tal como muestra la primera imagen de este post. Les dejo el código de ese plugin:

function retornar_ficha_proceso () {

  if ( 'proceso' == get_post_type() ) { 
    
$ficha = '
<table class="ficha_proceso">
<tr>
<td class="ficha_proceso_tit">CLIENTE:</td>
<td class="ficha_proceso_det">' . get_field('cliente') . '</td>
</tr>
<tr>
<td class="ficha_proceso_tit">NÚMERO DE CERTIFICADO:</td>
<td class="ficha_proceso_det">' . get_field('numero_de_certificado') . '</td>
</tr>
<tr>
<td class="ficha_proceso_tit">DOCUMENTO:</td>
<td class="ficha_proceso_det"><a href="' . wp_get_attachment_url(get_field('documento')) . '">' . get_the_title(get_field('documento')) . '</a></td>
</tr>
</table>
          
';          
        return $ficha;
        }
    }

function mostrar_proceso ($content) {

if ( 'proceso' == get_post_type() ) { 
$content = retornar_ficha_proceso();
}

return $content;
}

add_filter('the_content', 'mostrar_proceso', 1);


Esos es todo por ahora, hasta la próxima!!!

sábado, 13 de septiembre de 2014

viernes, 12 de septiembre de 2014

Publicar en WordPress desde Microsoft Access via XMLRCP Parte 5

Quinta entrega! Estamos investigando cómo conectar Microsoft Access con WordPress. En esta quinta entrega vamos a completar campos personalizados de un tipo de contenido vía XMLRCP. Recomiendo que leas las anteriores:

Parte 4: custom content type


Cambios a nuestro sitio de WordPress

El primera paso es agregar un plugin que nos facilite la creación de campos personalizados para nuestro tipo de contenido "proceso". Instalamos: Advanced Custom Fields.



Luego agregamos tres campos nuevos:
  • Número de certificado
  • Cliente
  • Documento



Vemos como aparecen estos nuevos campos en el momento de editar un "proceso":




El código

Sub PublicarEnWordPress()
 
    ' Datos de Autenticación
    CargarConstantes
    txtURL = SITIO
    txtUserName = USUARIO
    txtPassword = PASSWORD
    
    ' Datos del Post
    txtTitulo = "Certificado 6"
    txtContenido = "Este es un custom post de ejemplo publicado desde Microsoft Access"
    Dim txtCategorias(1) As String
    txtCategorias(1) = "Uncategorized"
    txtImagen = "25"
    txtTipoContenido = "proceso"
    txtCliente = "Cliente 1"
    txtNumeroCertificado = "APP-218539"
    txtDocumento = "25"
      
    ' ServerXMLHTTP
    Dim objSvrHTTP As ServerXMLHTTP
    Dim strT As String
    Set objSvrHTTP = New ServerXMLHTTP
  
    ' Autenticación
    objSvrHTTP.Open "POST", txtURL, False, CStr(txtUsuario), CStr(txtPassword)
    objSvrHTTP.setRequestHeader "Accept", "application/xml"
    objSvrHTTP.setRequestHeader "Content-Type", "application/xml"

    strT = strT & "<methodCall>"
    
    ' Acción
    strT = strT & "<methodName>wp.newPost</methodName>"
    
    ' General
    strT = strT & "<params>"
    strT = strT & "<param><value><string>0</string></value></param>"
    strT = strT & "<param><value>" & txtUserName & "</value></param>"
    strT = strT & "<param><value><string>" & txtPassword & "</string></value></param>"
    strT = strT & "<param>"
    
    strT = strT & "<struct>"
    
    ' Categorías
    strT = strT & "<member><name>categories</name><value><array>"
    strT = strT & "<data>"
    
    For i = 1 To UBound(txtCategorias)
        strT = strT & "<value>" & txtCategorias(i) & "</value>"
    Next i
    strT = strT & "</data>"
    strT = strT & "</array></value></member>"
    
    ' Título, contenido y fecha
    strT = strT & "<member><name>post_content</name><value><![CDATA[" & txtContenido & "]]></value></member>"
    strT = strT & "<member><name>post_title</name><value>" & txtTitulo & "</value></member>"
    strT = strT & "<member><name>dateCreated</name><value><dateTime.iso8601>" & Format(Now(), "yyyyMMdd") & "T" & Format(Now(), "hh:mm:ss") & "</dateTime.iso8601></value></member>"
    
    ' Imagen destacada
    strT = strT & "<member><name>post_thumbnail</name><value><![CDATA[" & txtImagen & "]]></value></member>"
    
    ' Tipo de contenido
    strT = strT & "<member><name>post_type</name><value>" & txtTipoContenido & "</value></member>"
    
    ' Campos personalizados
    strT = strT & "<member><name>custom_fields</name><value><array><data><value>"
    
    strT = strT & "<struct>"
    strT = strT & "<member><name>key</name><value>cliente</value></member>"
    strT = strT & "<member><name>value</name><value>" & txtCliente & "</value></member>"
    strT = strT & "</struct>"
    
    strT = strT & "<struct>"
    strT = strT & "<member><name>key</name><value>numero_de_certificado</value></member>"
    strT = strT & "<member><name>value</name><value>" & txtNumeroCertificado & "</value></member>"
    strT = strT & "</struct>"
    
    strT = strT & "<struct>"
    strT = strT & "<member><name>key</name><value>documento</value></member>"
    strT = strT & "<member><name>value</name><value>" & txtDocumento & "</value></member>"
    strT = strT & "</struct>"
    
    strT = strT & "</value></data></array></value></member>"
    
    ' Tipo de publicación
    strT = strT & "<member><name>post_status</name><value>publish</value></member>"
    
    strT = strT & "</struct>"
    strT = strT & "</param>"
    strT = strT & "</params>"
    strT = strT & "</methodCall>"
    
    ' Publicación
    objSvrHTTP.send strT

    ' Debug
    Debug.Print objSvrHTTP.responseText
    MsgBox objSvrHTTP.responseText

End Sub


La publicación

Vemos en esta imagen cómo se cargaron los campos personalizados:




Bibliografía


Nos vemos en la parte 6!!!

Publicar en WordPress desde Microsoft Access via XMLRCP Parte 4

En este cuarto artículo de conexión entre Microsoft Access y WordPress, vamos a trabajar con unas de las mejores funcionalidades de CMS que posee WordPress, los tipos de contenidos personalizados. Eso quiere decir que crearemos un nuevo ítem de tipo de contenido en forma remota a través de XMLRCP.

Como siempre, les recomiendo que previamente lean los artículos anteriores:



Un importante cambio de enfoque

Hasta ahora venimos trabajando con la API metaWeblog. A partir de ahora la abandonaremos porque no soporta tipos de contenido. En rigor, sí los soporta pero sólo si son páginas o posts. Con lo cual pasamos a utilizar sólo los métodos con prefijo wp que pueden encontrar en: http://codex.wordpress.org/XML-RPC_WordPress_API

Este pequeño detalle genera algunos cambios a nuestro código respecto a lo que veníamos viendo previamente. Remarqué esos cambios en bold.


Cambios en nuestro sitio de WordPress

Instalamos un plugin para manejar Tipos de Contenido, en este caso elijo "Custom Post Type UI"



Luego creamos un tipo de contenido nuevo, sin crearle aún campos personalizados (eso viene en la parte 5):




El código

Sub PublicarEnWordPress()
 
    ' Datos de Autenticación
    CargarConstantes
    txtURL = SITIO
    txtUserName = USUARIO
    txtPassword = PASSWORD
    
    ' Datos del Post
    txtTitulo = "Certificado 5"
    txtContenido = "Este es un custom post de ejemplo publicado desde Microsoft Access"
    Dim txtCategorias(1) As String
    txtCategorias(1) = "Uncategorized"
    txtImagen = "25"
    txtTipoContenido = "proceso"
      
    ' ServerXMLHTTP
    Dim objSvrHTTP As ServerXMLHTTP
    Dim strT As String
    Set objSvrHTTP = New ServerXMLHTTP
  
    ' Autenticación
    objSvrHTTP.Open "POST", txtURL, False, CStr(txtUsuario), CStr(txtPassword)
    objSvrHTTP.setRequestHeader "Accept", "application/xml"
    objSvrHTTP.setRequestHeader "Content-Type", "application/xml"

    strT = strT & "<methodCall>"
    
    ' Acción
    strT = strT & "<methodName>wp.newPost</methodName>"
    
    ' General
    strT = strT & "<params>"
    strT = strT & "<param><value><string>0</string></value></param>"
    strT = strT & "<param><value>" & txtUserName & "</value></param>"
    strT = strT & "<param><value><string>" & txtPassword & "</string></value></param>"
    strT = strT & "<param>"
    
    strT = strT & "<struct>"
    
    ' Categorías
    strT = strT & "<member><name>categories</name><value><array>"
    strT = strT & "<data>"
    
    For i = 1 To UBound(txtCategorias)
        strT = strT & "<value>" & txtCategorias(i) & "</value>"
    Next i
    strT = strT & "</data>"
    strT = strT & "</array></value></member>"
    
    ' Título, contenido y fecha
    strT = strT & "<member><name>post_content</name><value><![CDATA[" & txtContenido & "]]></value></member>"
    strT = strT & "<member><name>post_title</name><value>" & txtTitulo & "</value></member>"
    strT = strT & "<member><name>dateCreated</name><value><dateTime.iso8601>" & Format(Now(), "yyyyMMdd") & "T" & Format(Now(), "hh:mm:ss") & "</dateTime.iso8601></value></member>"
    
    ' Imagen destacada
    strT = strT & "<member><name>post_thumbnail</name><value><![CDATA[" & txtImagen & "]]></value></member>"
    
    ' Tipo de contenido
    strT = strT & "<member><name>post_type</name><value>" & txtTipoContenido & "</value></member>"
    
    ' Tipo de publicación
    strT = strT & "<member><name>post_status</name><value>publish</value></member>"
    
    strT = strT & "</struct>"
    strT = strT & "</param>"
    strT = strT & "</params>"
    strT = strT & "</methodCall>"
    
    ' Publicación
    objSvrHTTP.send strT

    ' Debug
    Debug.Print objSvrHTTP.responseText
    MsgBox objSvrHTTP.responseText

End Sub


La publicación

En caso que no abandonemos la API metaWeblog, obtendremos el siguiente mensaje de error:



Con la API wp podremos insertar el "proceso" tal como se ve en esta imagen:




Bibliografía



Hasta la próxima!